3

我们应该hasOwnProperty()在迭代对象的键时使用,因为Object.prototype可能会被污染,通过原型继承,也会污染所有对象的键。

因此,如果我不污染Object.prototype,我应该能够跳过hasOwnProperty()减慢for-in 循环的过程。它还将使代码更简单。

思路:先检查Object.prototype没有污染,再不要使用hasOwnProperty()

未污染的检查Object.prototype由以下功能完成。我将在我的代码中的一个战略位置调用它,它在脚本执行期间偶尔执行(就像在我要处理一堆数据之前)。如果对以下方面做了任何不好的事情,此功能只是提醒我Object.prototype

/* jshint -W089 */  // http://jslinterrors.com/the-body-of-a-for-in-should-be-wrapped-in-an-if-statement/
var checkObjectPrototypeNotAugmented = function() {
    /* jshint unused:false */   // Because key is considered unused
    // Check if there is any enumerable property on Object.prototype:
    for(var key in Object.prototype) {
        throw new Error("Object.prototype has been augmented with keys: " + Object.prototype.keys());
    }
};

注意:我/* jshint -W089 */发表评论是为了让 jshint 不会抱怨缺少hasOwnProperty().

问:这样可以吗?还有什么我应该注意的吗?或者我可以改进?


现在一些基准:

以下是 3 个 jsPerf 基准测试,它们显示了具有不同属性数量的对象的增益:

注意:Object.prototype每次迭代对象的属性时都会执行检查。在实际情况下,测试只需要执行一次:当整个页面加载时(然后不时确保没有脚本被无意修改Object.prototype)。因此,在实际情况下,您将获得“参考”测试的性能。但这表明,即使总是执行测试,它也保持得更快。

有趣的结果:

  • 不使用hasOwnProperty()任何一个都可以提供相同的速度或更快,具体取决于浏览器
  • 即使仅访问 1 个属性,Object.protoype在某些浏览器中,在每个 for-in 循环之前检查也可能比hasOwnProperty()! (但我不建议总是这样检查Object.prototype

相关:我们还看到,Object.keys()在某些浏览器中,对于大对象的使用速度可能更快,但对于小对象,它也可能更慢。但是使用Object.keys()会迫使您要么只支持浏览器 >= IE 9,要么在 IE <= 8 中Object.prototype添加一个polyfill。因此,为了与旧浏览器兼容,您必须选择Object.keys()checkObjectPrototypeNotAugmented()

4

0 回答 0