我知道很多创建JS对象的方法,但我不知道Object.create(null)。
题:
是否与以下内容完全相同:
var p = {}
与
var p2 = Object.create(null);
?
我知道很多创建JS对象的方法,但我不知道Object.create(null)。
题:
是否与以下内容完全相同:
var p = {}
与
var p2 = Object.create(null);
?
Answers:
它们绝对不是等效的。我正在写此答案,以更全面地解释为什么会有所作为。
var p = {};
创建一个对象,该对象继承的属性和方法Object。
var p2 = Object.create(null);
创建一个不继承任何内容的对象。
如果将对象用作地图,并且使用上面的方法1创建对象,则在地图中进行查找时必须格外小心。因为from的属性和方法Object是继承的,所以您的代码可能会遇到映射中存在从未插入的键的情况。例如,如果您在上进行了查找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,或null,或undefined,或0或NaN,等等。要检查某个属性是否存在,仍然需要使用Object.prototype.hasOwnProperty.call(p, someKey)。
Object.create(null)。我不希望做出这样的假设,即使您绝对正确地使用Object.create(null)了该代码,代码也可能会更改,该对象可能会替换为Object在某个时候继承的对象。hasOwnProperty一直有效。
{}了Object.create(null),它比如此流行得多,如果此时您的代码不小心抓住了继承的属性,则您可能有更大的bug需要担心。我只能看到人们使用Object.create(null)作为次要优化。
!!p[key]可以与Object.create(null)。不过hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)也不错啊
p因为每个方法都可以插入,因此变得不安全。
使用创建对象{}将创建一个对象,该对象的原型Object.prototype将从Object原型继承基本功能,而使用创建对象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;
}
注意:我出于好奇而编写了此文件,并且它仅是用简单的术语编写的,例如,我没有将属性描述符从第二个对象传输到返回对象。
-1在arguments.length>0?arguments[0]:-1;?
Object如果没有给出第一个参数,则保留原型。变量名在这里可能要好得多。
if (someKey in p) {