for/in循环
链接: http://www.mangguo.org/javascript-for-in-loop-trap/
链接: http://hi.baidu.com/cqgphper/item/cdf4d1b6bf7f6281eaba9301
链接:http://www.cnblogs.com/rubylouvre/p/3396042.html
关于for/in循环,先看下面的几个例子:
var array=[1,2,3,4,5]; var result = []; for(var i=0;i<array.length;i++){ result.push(array[i]); } alert(result.join(''));//12345
var array=[1,2,3,4,5 ]; var result=[]; for(var i in array){ result.push(array[i]); } alert(result.join(''));//12345
var array=[1,2,3,4,5]; Array.prototype.age=13; var result = []; for(var i=0;i<array.length;i++){ result.push(array[i]); } alert(result.join('')); //12345
var array=[1,2,3,4,5 ]; Array.prototype.age=6; var result=[]; for(var i in array){ result.push(array[i]); } alert(result.join('')); //123456
在执行for in的时候,javascript内部到底发生了什么?
我们在执行for in循环的时候,可以获得对象的可枚举属性,会将for/in中间的变量i赋值为对象的可枚举属性。
[变量i就是在此处被赋值的!]
而当我们向某个对象,或者在其原型链上添加了属性的时候, 那么它们在默认情况下是可枚举的,所以上面会把“6”打印出来
所以建议不要对数组执行for in循环,事实上,在高性能javascript这本书中,也强调了for in循环的不好,
因为它总是会访问该对象的原型,看下原型上是否有属性,这在无意中就给遍历增加了额外的压力。
当然,如果对象是从原型链中继承了该属性,或者根本没有Object.prototype.hasOwnProperty(name)属性,则返回false。
所以,我们可以通过hasOwnProperty来限定for/in循环。如下:
var array=[1,2,3,4,5 ]; Array.prototype.age=6; var result=[]; for(var i in array){ if(array.hasOwnProperty(i)){ result.push(array[i]); } } alert(result.join('')); //12345
for/in的输出顺序问题:
var data = { '4': 'first', '3': 'second', '2': 'third', '1': 'fourth' }; for (var i in data) { alert(i); //1 2 3 4 }
var obj = { "first":"first", "zoo":"zoo", "2":"2", "34":"34", "1":"1", "second":"second" }; for (var i in obj) { alert(i); };//1 2 34 first zoo second
原因是,for/in先把对象当中的非负整数键提出来,排序好输出,然后将剩下的按照先后顺序输出。
所以说,如果要按先后顺序输出,就不应该让纯数字作为js对象的KEY值。如下:
var obj = { "first":"first", "zoo":"zoo", "2":"2", "34u":"34", "1l":"1", "second":"second" }; for (var i in obj) { alert(i);}; //2 first zoo 2a 34u 1l second