4

我看到很多人这样做

Object.prototype.foo = 'HALLO';
var hash = {baz: 'quuz'};

for ( var v in hash ) {
  // Do not print property `foo`
  if ( hash.hasOwnProperty(v) ) {
    console.log( v + " is a hash property" );
  }
}

我的问题不是.hasOwnProperty每次您希望将 anObject用作哈希时都进行测试,为什么不直接在对象上设置.__proto__to呢?null†</p>

hash.prototype = null;
hash.__proto__ = null;

for ( var v in hash ) {
  // Do not print property `foo`
  console.log( v + " is a hash property" );
}

我注意到这__proto__是非标准的。但这仍然没有回答这个问题......

var foo = Object.create(null); Object.getPrototypeOf(foo);

这不可能是一个原始问题,但我找不到任何关于更改__proto__null以消除必须检查继承的缺点?这种方法有什么问题,似乎使代码更快(不必检查 的属性Object)和更清洁?

.prototype如果您打算将其作为未来的孩子,还有该财产。

4

2 回答 2

4

创建 [[Prototype]]'less 对象以避免在“散列”枚举期间进行基于 - 的检查并没有本质上的错误。hasOwnProperty

事实上,我知道的一些库(fuse.js 就是其中之一,IIRC)正是这样做的。

现在讨论实际问题:

  1. __proto__ 是非标准的。见我的同胞。表。注意 IE 是如何不支持 __proto__ 的,直到 IE9 包括在内。当然,IE9 支持Object.create,因此可以创建 [[Prototype]]'less 对象,Object.create(null)但仍然保留 IE6、IE7 和 IE8。哦,Opera <10.10,如您所见(不支持Object.create)。幸运的是,__proto__ 的存在(和功能)可以很容易地进行功能测试,这就是为什么不支持的浏览器可以采用hasOwnProperty基于或其他方式的原因。

  2. 从对象中移除 [[Prototype]] 会“移除”所有Object.prototype.*方法。自然。因此,例如,myHash.toString()(甚至myHash + '')现在会出错,除非您提供该哈希toString方法。valueOf,hasOwnProperty和所有其他Object.prototype.*方法同上。当然,这没什么大不了的,因为您总是可以定义这些方法(并且可能应该- 使它们专门用于哈希使用),但它仍然需要更多的工作。

到目前为止,没有发现任何关于这种方法的信息......我至少在 2 年前就在谈论它:) — http://groups.google.com/group/comp.lang.javascript/msg/9451c45080b5e9f0(也可能更早,但目前在 comp.lang.javascript 上找不到任何其他帖子)。在该线程中有更多关于浏览器行为与 __proto__ === null 的有趣发现。看看这个。

于 2011-06-03T15:27:57.890 回答
0

并非所有 JS 实现都具有__proto__非标准功能。

于 2011-05-28T03:27:12.910 回答