用Object.create(null)创buildJs对象?

我知道很多方法来创buildJS对象,但我不知道Object.create(null)之一。

所以…是完全一样的:

 var p = {} 

VS

 var p2 = Object.create(null); 

我认为他们是不相同的。 如果我没有弄错, {}.constructor.prototype == Object.prototypeObject.create(null)不从任何地方inheritance,因此根本没有任何属性。

换句话说:JavaScript对象默认从Objectinheritance,除非您显式创build指定null作为其原型的对象,如Object.create(null)

{}将相当于Object.create(Object.prototype)


在Chrome Devtool中,您可以看到Object.create(null)没有__proto

在这里输入图像说明

他们绝对不是等同的。 我正在写这个答案来更全面地解释为什么它有所作为。

  1. var p = {};

    创build一个从Objectinheritance属性和方法的Object

  2. 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; } 

:我写这个,出于好奇,它只是写在简单的术语,例如,我没有将属性描述符从第二个对象传递到返回对象。