我知道很多创建 JS 对象的方法,但我不知道Object.create(null)
's 的一种。
问题:
是不是完全一样:
var p = {}
对比
var p2 = Object.create(null);
?
我知道很多创建 JS 对象的方法,但我不知道Object.create(null)
's 的一种。
问题:
是不是完全一样:
var p = {}
对比
var p2 = Object.create(null);
?
它们绝对不等价。我写这个答案是为了更全面地解释为什么它会有所作为。
var p = {};
创建一个从 继承属性和方法的对象Object
。
var p2 = Object.create(null);
创建一个不继承任何东西的对象。
如果您将对象用作地图,并且使用上述方法 1 创建对象,则在地图中进行查找时必须格外小心。由于Object
继承自 from 的属性和方法,您的代码可能会遇到映射中存在您从未插入的键的情况。例如,如果您在 上进行查找toString
,您会找到一个函数,即使您从未将该值放在那里。你可以像这样解决这个问题:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
请注意,可以将某些内容分配给p.toString
,它会简单地覆盖 上的继承toString
函数p
。
请注意,您不能这样做,p.hasOwnProperty('toString')
因为您可能已将键“hasOwnProperty”插入到 中p
,因此我们强制它使用 中的实现Object
。
另一方面,如果您使用上面的方法2,那么您就不必担心Object
地图中出现的东西。
你不能用这样的简单检查属性的存在if
:
// Unreliable:
if (p[someKey]) {
// ...
}
该值可能是一个空字符串,可能是false
, or null
, or undefined
, or 0
, orNaN
等。要检查属性是否存在,您仍然需要使用Object.prototype.hasOwnProperty.call(p, someKey)
。
通过 using 创建对象{}
将创建一个原型为Object.prototype
继承原型的基本功能的Object
对象,而通过 using 创建对象Object.create(null)
将创建一个原型为 null 的空对象。
如果有人正在寻找实施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;
}
注意:出于好奇,我写了这个,它只是用简单的术语写的,例如,我没有将属性描述符从第二个对象转移到返回对象。
当您使用 Object.create(null) 创建一个对象时,这意味着您正在创建一个没有原型的对象。此处的null表示原型链的末端。然而,当您创建像 {} 这样的对象时,将添加对象原型。因此这是两个不同的对象,一个有原型,另一个没有原型。希望这有帮助