Web/JavaScript

[JavaScript] Object

llHoYall 2022. 6. 26. 14:03

Objects of JS are a collection of related data and/or functionality.

Objects can have multiple primitive types of values.

The primitive type of value is immutable, but the object type of value is mutable.

Property

An object is a set of zero or more properties, and the property consists of a key and a value.

If the value of the property is a function, it is called a method.

Key
Key can be string or symbol value. If we use other types of values, it is implicitly changed the type to string.
If the key of the property follows the identifier rules, we can omit the single-quotes or double-quotes.

Value
Value can be any value available in JS.

There are two methods to access properties.

  • . : dot notation
  • [] : bracket notation
const person = { name: "HoYa", age: 18 };
console.log(`${typeof person}, ${person.name}, ${person["age"]}`);
// object, HoYa, 18

If we access to nonexistence property, it returns undefined, not an error.

const person = { name: "HoYa" };
console.log(person.age); // undefined

If we declare existing property again, it is overwritten by the new value.

const person = { name: "HoYa" };
person.name = 'Park';
console.log(person.name); // Park

Properties can be added in run-time.

const person = { name: "HoYa" };
person.age = 18;
console.log(person); // { name: 'HoYa', age: 18 }

Create an Object

There are several ways to create objects.

Object Literal

const person = { name: "HoYa", age: 18 };
console.log(`${typeof person}, ${person.name}, ${person["age"]}`);
// object, HoYa, 18

The object literal method creates an object using { }(curly bracket).

From ES6 we can use property shorthand if the key and the value refer to the same variable.

let x = 1, y = 2;
const obj = {x, y};
console.log(obj); // { x: 1, y: 2 }

Object() Constructor Function

We can create an object using the Object() constructor function.

const obj = new Object({ name: "HoYa" });

There are also other built-in constructors for creating objects like String(), Number(), Boolean(), Function(), Array(), RegExp(), Date(), and Promose().

const strObj = new String('test');
const numObj = new Number(123);
const boolObj = new Boolean(true);
const funcObj = new Function('x', 'y', 'return x + y');
const arrObj = new Array(1, 2, 3);
const reObj = new RegExp(/pattern/i);
const dateObj = new Date();
const promiseObj = new Promise((resolve, reject) => {});

Constructor Function

We can create an object through a function.

function Person(name, age) {  
  this.name = name;
  this.age = age;
}

const person = new Person("John", 20);
console.log(`${typeof person}, ${person.name}, ${person.age}`);
// object, John, 20

It can be reduced by shorthand property.

function Person(name, age) {
  return { name, age };
}

const person = new Person("Eric", 37);
console.log(`${typeof person}, ${person["name"]}, ${person["age"]}`);
// object, Eric, 37

There is something to be careful about in this way.

  • Must be invoked with the new operator
  • Must omit the return statement

It can be used as a constructor function only if the above is observed.

From ES6, you can check whether it was called with new using new.target.

function Circle(radius) {
  if (!new.target) {
    return new Circle(radius);
  }

  this.radius = radius
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

Before ES5, the following methods may be used.

function Circle(radius) {
  if (!(this instanceof Circle) {
    return new Circle(radius);
  }

  this.radius = radius
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

Computed Property

This feature allows us to put an expression in brackets [ ], that will be computed and used as the property name.

const prefix = 'prop';
let i = 0;
const obj = {
  [`${prefix}${++i}`]: i,
  [`${prefix}${++i}`]: i,
  [`${prefix}${++i}`]: i
};
console.log(obj); // { prop1: 1, prop2: 2, prop3: 3 }

Computed property can be used when we access properties.

const person = { name: "Keith", age: 28 };

function printProperty(obj, key) {
  console.log(`${obj[key]}`);
}

printProperty(person, "name"); // Keith
printProperty(person, "age"); // 28

Let's see a more complex example.

const computedProperty = {
  test1: 1,
  test2: 2,
  test3: 3,
};

for (let i = 1; i < 4; ++i) {
  console.log(`${computedProperty['test' + i]}`);
}
// 1
// 2
// 3

Object Copy

There are two kinds of copy. One is the shallow copy and the other is the deep copy.

 

Let's see the shallow copy first.

const person1 = { name: "Andrew", age: 44 };
const person2 = person1;

console.log(`${person1.name}, ${person1.age}`);
// Andrew, 44
console.log(`${person2.name}, ${person2.age}`);
// Andrew, 44

person2.age = 47;

console.log(`${person1.name}, ${person1.age}`);
// Andrew, 47
console.log(`${person2.name}, ${person2.age}`);
// Andrew, 47

As you can see, I just change the age of person2, but the age of person1 is also changed.

Because the shallow copy just shares the memory space.

Therefore, if the property value of an object changes, it affects all the variables that refer to it.

 

Next, let's see the deep copy.

const person1 = { name: "Steve", age: 27 };
const person2 = {};
Object.assign(person2, person1);

console.log(`${person1.name}, ${person1.age}`);
// Steve, 27
console.log(`${person2.name}, ${person2.age}`);
// Steve, 27

person2.age = 37;

console.log(`${person1.name}, ${person1.age}`);
// Steve, 27
console.log(`${person2.name}, ${person2.age}`);
// Steve, 37

In this case, the person1 and person2 has its own memory space.