for...in主要用于对数组和对象的属性进行遍历。for ... in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操做。数组
语法:for (variable in object) {...}函数
variable:
每次迭代,一个不一样的属性名将会赋予
variable。
object:
可枚举属性被迭代的对象。
对数组操做spa
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会进行字符串拼接。prototype
对象操做code
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 并不可以保证返回的是按必定顺序的索引,可是它会返回全部可枚举属性,包括继承属性。对象
给原型添加属性以后,默认状况下枚举,会把原型属性一并输出,以下所示。因为它老是会访问该对象的原型,看下原型上是否有属性,这在无心中就给遍历增长了额外的压力。blog
例:继承
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
)。three
下面利用 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
在迭代进行时被添加到对象的属性,可能在以后的迭代被访问,也可能被忽略。一般,在迭代过程当中最好不要在对象上进行添加、修改或者删除属性的操做,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程当中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除以前被访问。
Note: 意思就是尽可能不要对数组对象使用for in遍历。