Objects

An object is a built-in type in JavaScript made up of properties (string type) and values (any type).

Essential:

github.com/getify/You-Dont-Know-JS

Description:

The Object type represents one of JavaScript’s data types. It is used to store various keyed collections and more complex entities. Objects can be created using the Object() constructor or the object initializer / literal syntax. Nearly all objects in JavaScript are instances of Object; a typical object inherits properties (including methods) from Object.prototype, although these properties may be shadowed (a.k.a. overridden). The only objects that don’t inherit from Object.prototype are those with null prototype, or descended from other null prototype objects.

Table of Contents

  1. 1. Creating
  2. 2. Prototype Chain
  3. 3. Setting a Property
  4. 4. Getters and Setters
  5. 5. Inspecting
  6. 6. Iterating
  7. 7. Cloning
  8. 8. Immutability
  9. 9. Documentation
  10. 10. Related notes

1. Creating

An object can be created 4 different ways:

Example:

When a function is invoked with new in front of it (a constructor call):

Description
1A new object is created (either a user-defined object type or one of the built-in object types that have a constructor function).
2The object is [[Prototype]] linked.
3The object is set as the this binding for that function call.
4Unless the function returns its own alternate object, the new-invoked function call will automatically return the newly constructed object.

2. Prototype Chain

When an object is created, a property, [[Prototype]], is set on the object. It allows an object to access properties of other objects. You can see this by creating an object in the browser’s console.

When you attempt to access an object property’s value on an object, for example obj.a, the engine invokes an internal [[Get]] operation. The engine will:

Description
1Look for the property on the object.
2If it can’t find it, it will then look for that property in the object that is referenced in the [[Prototype]] property.
3If the linked object doesn’t have the property, the engine will check that object’s linked object. This continues until the property is found or there are no more links. If no match is found, undefined is returned. This series of links between objects forms the prototype chain.

3. Setting a Property

When you attempt to set a value, myObject.myProperty = 1, the engine invokes an internal [[Put]] operation. If the property is present, the operation will check:

Description
1Is the property an accessor descriptor (see “Getters and Setters” section below)? Call the setter.
2Is the property a data descriptor with writable of false? Silently fail in non-strict mode, or throw TypeError in strict mode.
3Otherwise, set the value to the property.

A property on an object can be set in 3 different ways:

Example:

Does it look difficult so far? Coffee break before continuing!


4. Getters and Setters

Getters and setters are properties that call hidden functions to retrieve and set values. When you define a property to have either a getter or a setter, its definition becomes an accessor descriptor (as opposed to a data descriptor).

For accessor-descriptors, the value and writable characteristics of the descriptor are ignored. Instead, the engine considers the set and get characteristics of the property (as well as configurable and enumerable).

Example:

Remember to visit w3schools in order to get some extra information.


5. Inspecting

To test if an object has a property, use:

Step
1Object.hasOwn(..) to exclude the [[Prototype]] chain.
2in to include it.

Example:


6. Iterating

Iteration loop.

    ▪ for..in iterates over the list of enumerable properties on an object (including its [[Prototype]] chain).

    ▪ for..of with Object.entries doesn’t include the [[Prototype]] chain.

Example:

When iterating over an object, order of iteration isn’t guaranteed. If insertion order is required, use a Map instead of an object:

Example:


7. Cloning

An object can be cloned in 4 different ways:

Example:

The difference is only relevant if an object property has a value of another object:

    ▪ shallow: the reference is copied.

    ▪ deep: the object is duplicated and a reference to this new object will be used as the value.

{ ...obj } and structuredClone(..) are the preferred ways to do a shallow and deep clone.

Shallow versus deep.


8. Immutability

Object.freeze(..) creates an immutable object: an object that can’t be changed. It calls Object.seal(..) on the passed in object and marks all data accessor properties as writable: false. Their values can no longer be changed. This approach is the highest level of immutability that you can attain for an object.

Example:

In the last example, we got to see that the result of calling Object.freeze(object) only applies to the immediate properties of object itself, which means that it will prevent future property addition, removal, or value re-assignment operations only on object. If the value of those properties are objects themselves, those objects are not frozen and may be the target of property addition, removal, or value re-assignment operations.

Immutability: Deep Freeze

The deepFreeze() function checks if each property is an object and has not been frozen, then recursively freezes it. Finally, it freezes the main object, ensuring immutability throughout. Attempts to modify the object will throw errors, confirming its deeply frozen state:

Example:


9. Documentation

If you are still curious about objects and other matters, how about giving the fantastic Eloquent JavaScript a try? It’s free!


All Notes: