不要用for in語句對數組進行遍歷

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遍歷。

相關文章
相關標籤/搜索