JavaScript小提示:慎用for/in循环

对数组进行for-in遍历,会由于原型链扩展或者浏览器的不同实现而产生一系列预想不到的问题,建议使用基于length的for循环代替。

总结一些code时需要注意的地方。

慎用for/in循环。

一句话介绍:
对数组进行for-in遍历,会由于原型链扩展或者浏览器的不同实现而产生一系列预想不到的问题,建议使用基于length的for循环代替。

Q1: 由于一些库(比如mootools等),会扩展Array.prototype,for/in循环的时候会遍历数组的属性方法,导致取到预料之外的循环次数。由于扩展了Array.prototype,k对象的属性有1、2、3、$indexOf,遍历对象属性时会把$indexOf也遍历在内,与期待的结果不符。而k.length的值则不受影响,建议使用。

参考如下代码:

1
2
3
4
5
6
7
8
9
10
11
Array.prototype.$indexOf=function (a) { return  jQuery.inArray(a, this);  };
 
var k =[1,2,3];
 
for(a in k){
  console.log(a+":"+k[a]);      //you will get $indexOf for additional in this case.
}
 
for(var i=0,len=k.length;i<len;++i){  //it's correct here.
  console.log(i+":"+k[i]);
}

Q2: 另一个关于for/in的bug:

http://code.google.com/p/v8/issues/detail?id=164

1
2
var a = {"foo":"bar", "3": "3", "2":"2", "1":"1"};
for(var i in a) { console.log(i) };

期待的输出是:(firefox 3.6测试结果)
foo
3
2
1

部分浏览器的输出是:(chrome 9.0测试结果)
foo
1
2
3

EcmaScript 262-3rd 中对for in遍历的一些解释:

The mechanics of enumerating the properties is implementation dependent. The order of enumeration is defined by the object. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration.
对属性值的遍历依赖于继承的机制。访问对象属性的顺序依赖于对象自身。在遍历过程中属性可能被删除。(可以在遍历过程中删除对象属性。)在遍历到某属性之前删除了该属性,则该属性不会被访问到。一旦在遍历过程中给对象加入新属性,这些新属性不能保证会被访问到。

Enumerating the properties of an object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively; but a property of a prototype is not enumerated if it is “shadowed” because some previous object in the prototype chain has a property with the same name.
遍历的对象属性包括由原型链添加的属性,原型链上的原型链添加的属性,以此类推;原型链上如果有同名属性会覆盖上级原型链上的定义,遍历时会跳过那些被覆盖过的‘阴影’属性。

原文地址:http://www.decimage.com/web/javascript-tip-caution-for-in-loop.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值