在迭代对象以兼容 IE 时,是否真的需要 obj.hasOwnProperty(key)



为了兼容IE,我们决定对数组使用经典的for循环:

for (var i = 0; i < arr.length; ++i) { ... }

并为对象for循环添加obj.hasOwnProperty(key)

for (var key in obj) {
    if (!obj.hasOwnProperty(key)) continue;
    ...
}

但。。。这真的需要吗?

记得我查看了jQuery源代码,在迭代对象时没有找到这种情况。

另外,如果答案是肯定的,还有比向每个对象迭代添加if(!obj.hasOwnProperty(key)) continue;更短的解决方案吗?我的意思是以某种方式重写for...

需要明确的是:如果不是for (var k in o) { ... }我会使用:

foo (o, function (k) {
   ...    
});
function foo (o, callback) {
    for (var k in o) {
        callback (k);
    }
}

我只会在foo函数中添加一次if。但是考虑有很多对象for循环。有什么解决方案可以重写for吗?

你可以试试这个:

  function foo(o, callback) {
    var i, k = Object.keys( o );
    for (i = 0; i < k.length; ++i)
      callback(o[k[i]], k[i]);
  }

请注意,您可能应该将每个键的值传递给回调,而不仅仅是键。如果您只想在没有帮助程序函数的情况下循环访问对象,那么它是:

var keys = Object.keys( obj ), value;
for (var i = 0; i < keys.length; ++i) {
  value = obj[ keys[ i ] ];
  // ...
}

Object.keys()返回一个数组,因此您可以将数组样式迭代与索引一起使用。

Object.keys()函数在旧版浏览器中不存在,但您可以使用像 MDN 站点那样的 pollyfill。该函数不返回继承的属性,因此不需要.hasOwnProperty()测试。

如果您 100% 确定您的代码永远不会在其他代码修改了各种内置(以及就此而言,非内置)构造函数的原型对象的上下文中运行,那么您无需担心.hasOwnProperty()。 但是,由于此类问题引入的错误通常非常严重和奇怪,因此可能值得检查。

编辑 — 更高级的版本:

function foo(o, callback) {
  Object.keys(o).forEach(function(k) { callback( o[k], k ); });
}

这不是必需的。

只要确保正确编码数组循环,不要破坏原型。仅当您拥有无法省略的可怕编码的第三方模块时,才需要注意。

最新更新