javascript 使用 Object.create(null) 创建 JS 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15518328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating JS object with Object.create(null)?
提问by Royi Namir
I know a lot of ways to create JS objects but I didn't know the Object.create(null)
's one.
我知道很多创建 JS 对象的方法,但我不知道Object.create(null)
's 的一种。
Question:
问题:
is it exactly the same as:
是不是完全一样:
var p = {}
vs
对比
var p2 = Object.create(null);
?
?
回答by Peter Herdenborg
They are not equivalent. {}.constructor.prototype == Object.prototype
while Object.create(null)
doesn't inherit from anything and thus has no properties at all.
它们不是等价的。{}.constructor.prototype == Object.prototype
whileObject.create(null)
不继承任何东西,因此根本没有任何属性。
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)
.
换句话说:javascript 对象默认从 Object 继承,除非您显式地使用 null 作为其原型创建它,例如:Object.create(null)
。
{}
would instead be equivalent to Object.create(Object.prototype)
.
{}
相反,将等效于Object.create(Object.prototype)
.
In Chrome Devtool you can see that Object.create(null)
has no __proto__
property, while {}
does.
在 Chrome Devtool 中,您可以看到它Object.create(null)
没有__proto__
属性,而{}
有。
回答by doug65536
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.
var p = {};
创建一个从 继承属性和方法的对象
Object
。var p2 = Object.create(null);
创建一个不继承任何东西的对象。
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:
如果您将对象用作地图,并且使用上述方法 1 创建对象,则在地图中进行查找时必须格外小心。由于Object
继承自 from 的属性和方法,您的代码可能会遇到映射中存在您从未插入的键的情况。例如,如果您在 上进行查找toString
,您会找到一个函数,即使您从未将该值放在那里。你可以像这样解决这个问题:
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
.
请注意,可以将某些内容分配给p.toString
,它会简单地覆盖 上的继承toString
函数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
.
请注意,您不能这样做,p.hasOwnProperty('toString')
因为您可能已将键“hasOwnProperty”插入到 中p
,因此我们强制它使用 中的实现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.
另一方面,如果您使用上面的方法2,那么您就不必担心Object
地图中出现的东西。
You can't check for the existence of a property with a simple if
like this:
你不能用这样的简单检查属性的存在if
:
// 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)
.
该值可能是一个空字符串,可能是false
, or null
, or undefined
, or 0
, orNaN
等。要检查属性是否存在,您仍然需要使用Object.prototype.hasOwnProperty.call(p, someKey)
。
回答by Praveen Kishor
Creating objects by using {}
will create an object whose prototype is Object.prototype
which inherits the basic functions from Object
prototype while creating objects by using Object.create(null)
will create an empty object whose prototype is null.
通过 using 创建对象{}
将创建一个原型为Object.prototype
继承原型的基本功能的Object
对象,而通过 using 创建对象Object.create(null)
将创建一个原型为 null 的空对象。
回答by user13624607
When you create an Object with Object.create(null) that means you are creating an Object with no prototype.nullhere means end of prototype chain. Nevertheless when you create an object like {} Object prototype will be added. Hence these are two different objects, one with prototype another without prototype.Hope this helps
当您使用 Object.create(null) 创建一个对象时,这意味着您正在创建一个没有原型的对象。此处的null表示原型链的末端。然而,当您创建像 {} 这样的对象时,将添加对象原型。因此这是两个不同的对象,一个有原型,另一个没有原型。希望这有帮助
回答by Aravind
If someone is looking for implementing Object.create(null)
, just to know how it works. It is written using __proto__
which is non-standard and hence, I do not recommend it.
如果有人正在寻找实施Object.create(null)
,只是想知道它是如何工作的。它是使用__proto__
非标准编写的,因此我不推荐它。
function objectCreateMimic()
{
/*optional parameters: prototype_object, own_properties*/
var P = arguments.length>0?arguments[0]:-1;
var Q = arguments.length>1?arguments[1]:null;
var o = {};
if(P!==null && typeof P === "object")
{
o.__proto__ = P;
}
else if(P===null)
{
o.__proto__ = null;
}
if(Q!==null && typeof Q === "object")
{
for(var key in Q)
{
o[key] = Q[key];
}
}
return o;
}
Note: I wrote this, out of curiosity, and it is only written in simple terms, for instance, I am not transferring the property descriptors from the second object to the return object.
注意:出于好奇,我写了这个,它只是用简单的术语写的,例如,我没有将属性描述符从第二个对象转移到返回对象。