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


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

在迭代進行時被添加到對象的屬性,可能在之后的迭代被訪問,也可能被忽略。通常,在迭代過程中最好不要在對象上進行添加、修改或者刪除屬性的操作,除非是對當前正在被訪問的屬性。這里並不保證是否一個被添加的屬性在迭代過程中會被訪問到,不保證一個修改后的屬性(除非是正在被訪問的)會在修改前或者修改后被訪問,不保證一個被刪除的屬性將會在它被刪除之前被訪問。

Note: 意思就是盡量不要對數組對象使用for in遍歷。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM