用Object.create(null)创buildJs对象?
我知道很多方法来创buildJS对象,但我不知道Object.create(null)
之一。
所以…是完全一样的:
var p = {}
VS
var p2 = Object.create(null);
?
我认为他们是不相同的。 如果我没有弄错, {}.constructor.prototype == Object.prototype
而Object.create(null)
不从任何地方inheritance,因此根本没有任何属性。
换句话说:JavaScript对象默认从Objectinheritance,除非您显式创build指定null作为其原型的对象,如Object.create(null)
。
{}
将相当于Object.create(Object.prototype)
。
在Chrome Devtool中,您可以看到Object.create(null)
没有__proto
。
他们绝对不是等同的。 我正在写这个答案来更全面地解释为什么它有所作为。
-
var p = {};
创build一个从
Object
inheritance属性和方法的Object
。 -
var p2 = Object.create(null);
创build一个不会inheritance任何东西的对象。
如果您将对象用作地图,并使用上述方法1创build对象,则在地图中进行查找时必须格外小心。 由于Object
的属性和方法是inheritance的,因此您的代码可能会遇到映射中没有插入键的情况。 例如,如果你对toString
进行了查找,你会发现一个函数,即使你从来没有把这个值放在那里。 你可以像这样解决这个问题:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) { // we actually inserted a 'toString' key into p }
请注意,将某些内容分配给p.toString
是很好的,它将简单地覆盖p
上的inheritance的toString
函数。
请注意,您不能仅仅执行p.hasOwnProperty('toString')
因为您可能已经在p
插入了一个键“hasOwnProperty”,所以我们强制它使用Object
的实现。
另一方面,如果使用上面的方法2,则不必担心映射中出现的Object
。
你不能用简单的方法来检查一个属性是否存在:
// Unreliable: if (p[someKey]) { // ... }
这个值可能是一个空string,可能是false
,或null
,或者undefined
,或者是0
或者NaN
等等。为了检查一个属性是否存在,你仍然需要使用Object.prototype.hasOwnProperty.call(p, someKey)
。
如果有人正在寻找实现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; }
注 :我写这个,出于好奇,它只是写在简单的术语,例如,我没有将属性描述符从第二个对象传递到返回对象。