为了兼容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 ); });
}
这不是必需的。
只要确保正确编码数组循环,不要破坏原型。仅当您拥有无法省略的可怕编码的第三方模块时,才需要注意。