不要用for in语句对数组进行遍历

来源:互联网 发布:k歌达人 网络异常 编辑:程序博客网 时间:2024/06/05 17:20

for...in主要用于对数组和对象的属性进行遍历。for ... in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。

语法for (variable in object) {...}

variable:每次迭代,一个不同的属性名将会赋予variable。
object:可枚举属性被迭代的对象。

对数组操作

复制代码
        var a=[5,4,3,2,1];        var x=0;        console.log(typeof x);//number        for (x in a) {            console.log("a["+x+"]: "+a[x]);            console.log(typeof x);//string        }        console.log(x);//4        console.log(typeof x);//string//output://        a[0]: 5//        a[1]: 4//        a[2]: 3//        a[3]: 2//        a[4]: 1
复制代码

可以发现在for in函数中变量以字符串的形式出现,这时候在函数中操作a[x+1]的话是无效的,x+1会进行字符串拼接。

对象操作

复制代码
var obj={"1":"first",   "two":"zoo",  "3":"2",  "three":"34",  "4":"1",  "2":"second"};for (var i in obj) {     console.log(i+":"+obj[i]);};//output://1:first//2:second//3:2//4:1//two:zoo//three:34
复制代码

可发现,for...in 并不能够保证返回的是按一定顺序的索引,但是它会返回所有可枚举属性,包括继承属性。

给原型添加属性之后,默认情况下枚举,会把原型属性一并输出,如下所示。由于它总是会访问该对象的原型,看下原型上是否有属性,这在无意中就给遍历增加了额外的压力。

例:

复制代码
function fun4(){var a=[1,2,3,4,5];Array.prototype.age=13;for(var i in a){console.log("a["+i+"]: "+a[i]);}}//outuput://a[0]: 1//a[1]: 2//a[2]: 3//a[3]: 4//a[4]: 5//a[age]: 13
复制代码

解决方法:

如果你只要考虑对象本身的属性,而不是它的原型,那么使用 getOwnPropertyNames() 或执行  hasOwnProperty() 来确定某属性是否是对象本身的属性 (也能使用propertyIsEnumerable)。

下面利用 hasOwnProperty() 的方法使隐藏的继承属性不会被显示。如果该对象是从原型链中继承了该属性,或者根本没有这样的一个属性,则返回false。如果某个对象具有给定名称的属性,则返回true。

复制代码
function fun4(){var a=[1,2,3,4,5];Array.prototype.age=13;for(var i in a){  if( a.hasOwnProperty( i ) ) {    console.log("a["+i+"]: "+a[i]);  }}}//outuput://a[0]: 1//a[1]: 2//a[2]: 3//a[3]: 4//a[4]: 5
复制代码

在迭代进行时被添加到对象的属性,可能在之后的迭代被访问,也可能被忽略。通常,在迭代过程中最好不要在对象上进行添加、修改或者删除属性的操作,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除之前被访问。

0 0
原创粉丝点击