In both Vue and Vuex sources, the authors use object.create (NULL) to initialize a new Object. Why not use the more concise {}?
There’s also a lot of discussion going on in the developer community like The SegmentFault and Stack Overflow, and here’s a summary of what’s going on and what’s new.
The definition of the Object. The create ()
Repeat the MDN definition:
Object.create(proto,[propertiesObject])
Copy the code
- Proto: the prototype object for the newly created object
- PropertiesObject: optional. The enumerable property to be added to the new object (the newly added property is its own property, not a property on its prototype chain).
Here’s an example:
const car = {
isSportsCar: false,
introduction: function () {
console.log(`Hi girl, this is a ${this.name}.
Do you like to have a drink with me ? ${this.isSportsCar}`); }}; Const porsche = object.create (car,{//color is the color of the porsche; //color is the color of the porsche;true,
configurable:true,
value:'yellow'
},
//typeBecomes the accessor attribute of porschetype:{// The properties of writable, freely and other information are set by default if they are not explicitly setfalse// If you want to change a regular car to a convertible, it will cost a little too much, so make it unconfigurable:function() {return 'convertible'},
set:function(value){"change this car to",value}
}
});
porsche.name = "Porsche 911"; // "name"is"porsche"Properties of the"car"Porsche. IsSportsCar =true; // Inherited attributes can be overwritten with porsche.introduction(); // expected output:"Hi girl, this is a Porsche 911. Do you like to have a drink with me ? true"
Copy the code
The definition of object.create () is pretty simple, just make sense of the example above.
Object. The create (), {… The difference between}
Let’s take a look at what the object we often create with {} looks like:
Var o = {a: 1}; console.log(o)Copy the code
Print the following in the Chrome Console:
As you can see from the figure above, the newly created Object inherits its own methods, such as hasOwnProperty and toString, which can be directly used on the new Object.
Take a look at creating objects using object.create () :
var o = Object.create(null,{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
Copy the code
Print the following in the Chrome Console:
As you can see, the newly created Object has no properties on the prototype chain other than its own property a, that is, nothing that inherits from Object. If we call o.tostring (), we will report Uncaught TypeError.
You may notice that the first argument is null. That is, null is set to the stereotype of the newly created object, so there will be no properties on the stereotype chain. Let’s change the above example again:
var o = Object.create({},{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
Copy the code
Change null to {}, what is the result? Print the following in the Chrome Console:
As we can see, the object created this way is very similar to the object created using {}, but there is one more difference: there is an extra layer of proto nesting.
Let’s make one last change:
var o = Object.create(Object.prototype,{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
Copy the code
Chrome Console prints below:
This is exactly the same as the object created with {}. By now, I’m sure the difference is pretty clear.
Use scenarios of object.create (NULL)
Returning to the question at the beginning of this article, why do many source code authors use object.create (NULL) to initialize a new Object? Is this a writer’s habit or a best practice?
No, this is not something the author used without thinking about it, nor is it a best practice in javascript programming. It is something that needs to be done on a case-by-case basis.
Let’s further compare the difference between object.create (null) and {} to create control objects:
Print in Chrome as follows:
As you can see from the figure above, the object created with create has No properties and displays No properties. We can use it as a very clean map. We can define our own hasOwnProperty, toString methods, either intentionally or accidentally. We don’t have to worry about overwriting methods of the same name on the prototype chain. Here’s an example:
//Demo1: var a= {... Omit many properties and methods... }; // If you want to check if a has a property named toString, you must check as follows:if(Object.prototype.hasOwnProperty.call(a,'toString')) {... } // Why not use a.hasownProperty (a.hasownProperty)'toString')? Because you might have added a custom hasOwnProperty to a // you can't use the following method to determine this because the toString method on the prototype exists:if(a.tostring){} //Demo2: var a= object.create (null) // You can use the following method:if(a.toString){}
Copy the code
Another reason to use create(null) is that when we use for.. The in loop iterates over the property chain of the Object stereotype. Create (null) eliminates the need to check the property. Alternatively, we can use object.keys [] directly.
Conclusion:
- When you need a very clean and highly customizable object to use as a data dictionary;
- Want to save
hasOwnProperty
A performance penalty and a little less code to slack off on
With the Object. The create (null)!!!! Otherwise, use {}.
The above