“This is the 13th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Today we’ll sort out the contents related to Object.

On the MDN introduced: JavaScript Object – | MDN (mozilla.org)

Make immutable objects

Object.freeze

We all know that there is a concept in functional programming called a pure function, which is a function with no side effects, the same result for the same input, independent of external variables, cannot change the value of the input.

A = ‘XXX’ and we can easily change the actual contents of object obj. Is there a way for the body of the function to access the contents of the input parameter OBj without making sure that no one inside the body can modify it?

The answer is object.freeze ()

Object.freeze() freezes an Object so that it cannot be modified again.

const a = { val: 233}
Object.freeze(a)
a.val = 250
console.log(a){val: 233}
Copy the code

As well as object.seal () and object.preventExtensions (), the differences are as follows:

freeze seal preventExtensions
None of them can be modified (can’t change values, stereotypes, can’t add or delete properties, can’t be configured) New attributes cannot be added and cannot be configured New attributes cannot be added

Application scenario: The React function is the prop input parameter of the component. In the framework layer, wrap the props with object.freeze () and pass it to the component function to ensure that the developer cannot modify the prop value in the component.

Get the original type

Object.prototype.toString.call

Typeof can be used to identify primitive types, but null and non-null objects and arrays cannot be distinguished. Want to do this, you can use the Object. The prototype. ToString. Call.

console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(null))// [object Null]
console.log(Object.prototype.toString.call({})) // [object Object]
Copy the code

Note that the prototype attribute is not missing, as the following code is illegal:

Object.toString.call([])
Copy the code

This will report TypeError

Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function
    at Array.toString (<anonymous>)
Copy the code

Reason is that the Object and the Boolen, Number, String and other constructors are themselves rewrite the toString method, this method and the Object. The prototype. ToString is totally different. Only the latter can get the original type.

Create a new object based on an object

Object.create()

Object has such a feature that when you access a field B of object A, i.e. access A.B, if B is not a property of A, js will try to find the nearest prototype with b property along the chain of a’s prototype. The object.create (obj) method creates an empty Object using obj as a prototype.

const a = Object.create({b: 1})
console.log(a)/ / {}
console.log(a.b)/ / 1
Copy the code

One application of Object.create is to simulate hash tables. Before the standard data structure of ES6 Map and Set came out, the method to implement Map was generally as follows:

const map = Object.create(null)
/ / to add or change
map.a = 1
/ / delete
delete map.a
/ / check
'a' in map
Copy the code

To simulate hash tables, we use Object.create(null) instead of {} directly because the latter stereotype has some other methods whose names may be identical to user-set keys, while the former stereotype sets null without this problem.

In addition, another application scenario is to construct prototype chains. Among the design patterns of software engineering, there is a pattern called the chain of responsibility pattern, which has the following concept:

This avoids coupling between the sender and receiver of the request by giving multiple objects the opportunity to process the request. These objects are joined in a chain, and the request is passed along the chain until an object processes it.

The prototype chain is a natural chain of responsibility pattern. We can wrap object.create as a function that builds the nodes of the chain of responsibility.

function createBuildNodeFn() {
    let last;
    return (options) = > {
        last = Object.create(last ?? null);
        Object.assign(last, options);
        return last;
    };
}
const buildNode = createBuildNodeFn();
const node1 = buildNode({
   handleXXX() {
   // ...}});const node2 = buildNode({
   handleXXX() {
   / /...}}); node2.handleXXX()Copy the code

Object property descriptor

Object.getOwnPropertyDescriptor

The object property descriptor is used to describe the properties of an object property, which is an object containing the following fields:

  • value
  • enumerable
  • configurable
  • writable
const c = { b: undefined};
console.log(Object.getOwnPropertyDescriptor(c, 'b'))
// {value: undefined, writable: true, enumerable: true, configurable: true}
Copy the code

By default, all three fields except value are true, but Object.create, Object.defineProperties, and Object.defineProperty all have opportunities to modify Object property descriptors. Details can be found at MDN (mozilla.org).

  • If the 64x is set to false, the property descriptor cannot be modified again and the property cannot be deleted and deleted.
  • Enumerable is false and cannot be iterated by the for loop
  • This value cannot be modified if writable is set to false.