Creating JS object with Object.create(null)?
They are not equivalent. {}.constructor.prototype == Object.prototype
while Object.create(null)
doesn't inherit from anything and thus has no properties at all.
In other words: A javascript object inherits from Object by default, unless you explicitly create it with null as its prototype, like: Object.create(null)
.
{}
would instead be equivalent to Object.create(Object.prototype)
.
In Chrome Devtool you can see that Object.create(null)
has no __proto__
property, while {}
does.
They are definitely not equivalent. I'm writing this answer to more fully explain why it makes a difference.
var p = {};
Creates an object that inherits the properties and methods from
Object
.var p2 = Object.create(null);
Creates an object that doesn't inherit anything.
If you are using an object as a map, and you create an object using method 1 above, then you have to be extra careful when doing lookups in the map. Because the properties and methods from Object
are inherited, your code may run into a case where there are keys in the map that you never inserted. For example, if you did a lookup on toString
, you would find a function, even though you never put that value there. You can work around that like this:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Note that it is fine to assign something to p.toString
, it will simply override the inherited toString
function on p
.
Note that you can't just do p.hasOwnProperty('toString')
because you may have inserted a key "hasOwnProperty" into p
, so we force it to use the implementation in Object
.
On the other hand, if you use method 2 above, then you won't have to worry about things from Object
appearing in the map.
You can't check for the existence of a property with a simple if
like this:
// Unreliable:
if (p[someKey]) {
// ...
}
The value might be an empty string, might be false
, or null
, or undefined
, or 0
, or NaN
, etc. To check whether a property exists at all, you would still need to use Object.prototype.hasOwnProperty.call(p, someKey)
.