我知道很多创建 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表示原型链的末端。然而,当您创建像 {} 这样的对象时,将添加对象原型。因此这是两个不同的对象,一个有原型,另一个没有原型。希望这有帮助