通过Object w / prototype null的ECMAScript关联数组?

时间:2011-05-28 03:23:33

标签: javascript ecma262 ecmascript-5

我看到很多人这样做

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作为哈希时,为什么不在对象上设置Object.__proto__,而不是测试null? †

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属性。

2 个答案:

答案 0 :(得分:4)

没有内在错误创建[[Prototype]]'较少的对象,以避免在“hash”枚举期间基于hasOwnProperty的检查。

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

现在谈到实际问题:

  1. __ proto__ 非标准。查看我的compat. table。请注意IE在IE9之前不支持__proto__。当然,IE9支持Object.create,因此可以使用Object.create(null)创建[[Prototype]]'较少的对象,但仍然留下IE6,IE7和IE8。哦,Opera< 10.10,你可以看到(不支持Object.create)。幸运的是,__ proto__的存在(和功能)可以很容易地进行功能测试,这就是为什么可以使非支持浏览器采用基于hasOwnProperty或其他路径的原因。

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

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

答案 1 :(得分:0)

并非所有JS实现都具有__proto__,因为它是非标准功能。