用 Object.create (null)创建 JS 对象是否与{}相同?

我知道很多创建 JS 对象的方法,但是我不知道 Object.create(null)的方法。

问题:

是不是和:

var p = {}

var p2 = Object.create(null);

39256 次浏览

它们是不等价的。 {}.constructor.prototype == Object.prototypeObject.create(null)不继承任何东西,因此没有任何属性。

换句话说: javascript 对象在默认情况下从 Object 继承,除非您显式地将 null 作为原型来创建它,比如: Object.create(null)

取而代之的是 {}等价于 Object.create(Object.prototype)


在 ChromeDevtool 中,你可以看到 Object.create(null)没有 __proto__属性,而 {}有。

enter image description here

它们绝对不是等价的。我写这个答案是为了更全面地解释为什么它会有所不同。

  1. var p = {};

    创建一个从 Object继承属性和方法的对象。

  2. var p2 = Object.create(null);

    创建一个不继承任何内容的对象。

如果使用对象作为映射,并且使用上面的方法1创建对象,那么在映射中进行查找时必须格外小心。因为继承了 Object的属性和方法,所以代码可能会遇到映射中有从未插入的键的情况。例如,如果对 toString进行查找,就会找到一个函数,即使您从未将该值放在那里。你可以这样解决:

if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}

请注意,可以为 p.toString赋值一些内容,它只会覆盖 p上继承的 toString函数。

请注意,您不能仅仅执行 p.hasOwnProperty('toString'),因为您可能已经在 p中插入了一个键“ hasOwnProperty”,所以我们强制它使用 Object中的实现。

另一方面,如果您使用上面的方法2,那么您就不必担心来自 Object的东西会出现在地图中。

你不能用这样一个简单的 if来检查一个属性是否存在:

// Unreliable:
if (p[someKey]) {
// ...
}

值可以是空字符串,也可以是 falsenullundefined0NaN等等。要检查一个属性是否存在,您仍然需要使用 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;
}

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

使用 {}创建对象将创建一个原型为 Object.prototype的对象,它继承了 Object原型的基本函数,而使用 Object.create(null)创建对象将创建一个原型为 null 的空对象。

When you create an Object with Object.create(null) that means you are creating an Object with no prototype.无效 here means end of prototype chain. Nevertheless when you create an object like {} Object prototype will be added. 因此,这是两个不同的对象,一个有原型,另一个没有原型。希望这有所帮助