javascript 使用 Object.create(null) 创建 JS 对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15518328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 01:04:07  来源:igfitidea点击:

Creating JS object with Object.create(null)?

javascript

提问by Royi Namir

I know a lot of ways to create JS objects but I didn't know the Object.create(null)'s one.

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

Question:

问题:

is it exactly the same as:

是不是完全一样:

var p = {}

vs

对比

var p2 = Object.create(null);

?

?

回答by Peter Herdenborg

They are not equivalent. {}.constructor.prototype == Object.prototypewhile Object.create(null)doesn't inherit from anything and thus has no properties at all.

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

In other words: A javascript object inherits from Object by default, unless you explicitly create it with null as its prototype, like: Object.create(null).

换句话说:javascript 对象默认从 Object 继承,除非您显式地使用 null 作为其原型创建它,例如:Object.create(null)

{}would instead be equivalent to Object.create(Object.prototype).

{}相反,将等效于Object.create(Object.prototype).



In Chrome Devtool you can see that Object.create(null)has no __proto__property, while {}does.

在 Chrome Devtool 中,您可以看到它Object.create(null)没有__proto__属性,而{}有。

enter image description here

在此处输入图片说明

回答by doug65536

They are definitely not equivalent. I'm writing this answer to more fully explain why it makes a difference.

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

  1. var p = {};

    Creates an object that inherits the properties and methods from Object.

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

    Creates an object that doesn't inherit anything.

  1. var p = {};

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

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

    创建一个不继承任何东西的对象。

If you are using an object as a map, and you create an object using method 1 above, then you have to be extra careful when doing lookups in the map. Because the properties and methods from Objectare inherited, your code may run into a case where there are keys in the map that you never inserted. For example, if you did a lookup on toString, you would find a function, even though you never put that value there. You can work around that like this:

如果您将对象用作地图,并且使用上述方法 1 创建对象,则在地图中进行查找时必须格外小心。由于Object继承自 from 的属性和方法,您的代码可能会遇到映射中存在您从未插入的键的情况。例如,如果您在 上进行查找toString,您会找到一个函数,即使您从未将该值放在那里。你可以像这样解决这个问题:

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

Note that it is fine to assign something to p.toString, it will simply override the inherited toStringfunction on p.

请注意,可以将某些内容分配给p.toString,它会简单地覆盖 上的继承toString函数p

Note that you can't just do p.hasOwnProperty('toString')because you may have inserted a key "hasOwnProperty" into p, so we force it to use the implementation in Object.

请注意,您不能这样做,p.hasOwnProperty('toString')因为您可能已将键“hasOwnProperty”插入到 中p,因此我们强制它使用 中的实现Object

On the other hand, if you use method 2 above, then you won't have to worry about things from Objectappearing in the map.

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

You can't check for the existence of a property with a simple iflike this:

你不能用这样的简单检查属性的存在if

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

The value might be an empty string, might be false, or null, or undefined, or 0, or NaN, etc. To check whether a property exists at all, you would still need to use Object.prototype.hasOwnProperty.call(p, someKey).

该值可能是一个空字符串,可能是false, or null, or undefined, or 0, orNaN等。要检查属性是否存在,您仍然需要使用Object.prototype.hasOwnProperty.call(p, someKey)

回答by Praveen Kishor

Creating objects by using {}will create an object whose prototype is Object.prototypewhich inherits the basic functions from Objectprototype while creating objects by using Object.create(null)will create an empty object whose prototype is null.

通过 using 创建对象{}将创建一个原型为Object.prototype继承原型的基本功能的Object对象,而通过 using 创建对象Object.create(null)将创建一个原型为 null 的空对象。

回答by user13624607

When you create an Object with Object.create(null) that means you are creating an Object with no prototype.nullhere means end of prototype chain. Nevertheless when you create an object like {} Object prototype will be added. Hence these are two different objects, one with prototype another without prototype.Hope this helps

当您使用 Object.create(null) 创建一个对象时,这意味着您正在创建一个没有原型的对象。此处的null表示原型链的末端。然而,当您创建像 {} 这样的对象时,将添加对象原型。因此这是两个不同的对象,一个有原型,另一个没有原型。希望这有帮助

回答by Aravind

If someone is looking for implementing Object.create(null), just to know how it works. It is written using __proto__which is non-standard and hence, I do not recommend it.

如果有人正在寻找实施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;
}

Note: I wrote this, out of curiosity, and it is only written in simple terms, for instance, I am not transferring the property descriptors from the second object to the return object.

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