首頁  >  文章  >  web前端  >  javascript中for與for in區別,以及為什麼不建議使用for in

javascript中for與for in區別,以及為什麼不建議使用for in

伊谢尔伦
伊谢尔伦原創
2017-07-17 14:13:363287瀏覽

js中遍歷陣列的有兩種方式

var array=['a']
//标准的
for循环
for(var i=1;i<array.length;i++){
    alert(array[i])
}
//
foreach
循环
for(var i in array){
    alert(array[i])
}

正常情況下上面兩種遍歷陣列的方式結果一樣。首先說兩者的第一個區別

標準的for循環中的i是number類型,表示的是數組的下標,但是foreach循環中的i表示的是數組的key是string類型,因為js中一切都是物件。自己試試 alert(typeof i);這個差別是小問題。現在我加上以下程式碼,上面的執行結果就不一樣了。

//扩展了js原生的Array
Array.prototype.test=function()
 
}

試試看上面的程式碼執行什麼。我們發現標準的for循環任然真正的對數組循環, 但是此時foreach循環對我剛才寫的test方法寫打印出來了。這就是for與foreach遍歷數組的最大區別,如果我們在專案採用的是用foreach遍歷數組,假設有一天誰不小心自己為了擴展js原生的Array類,或者引入一個外部的js框架也擴展了原生Array 。那問題就來了。

為什麼不要用for in語句 ?

關鍵字:原生Array類別、擴充Array類別 
for in 語句對陣列物件進行遍歷潛在的bug在於:如果原生Array類別被其他的js腳本函式庫進行了原型擴充(例如多加一個toJSON方法即Array.prototype.toJSON=xxxx),那麼用for in遍歷擴充後的Array物件的邏輯將與遍歷原生Array物件的邏輯發生差異。 
舉個簡單的例子, 

var x=[1]; 
for(var s in x){ 
alert(s); 
};

按常理,如果Array是原生js類,上面語句應該只執行一次alert方法,且s為數組的索引0。但是,如果Array類別被擴充了,多了一個toJSON方法,那麼上面的語句將執行兩次alert,第一次s為索引0,第二次s為方法名稱'toJSON'。

如果你設計的程式碼的邏輯以原生Array類為基準,在某一天你的同事在頁裡面引用了一個第三方的JS庫,這個庫又恰好擴展了Array類,結果將很難想像,很有可能原來的程式碼邏輯將不再成立。 

關於這個擴充原生JS類別的函式庫,很有名的一個就是prototype.js,它給Array類別擴充了很多方法諸如toJSON,each等等。我現在明白為啥jquery的創始人曾經對prototype火大了(不少人因為特殊原因在一個頁面裡用jquery同時又用prototype,會有很多意料之外的衝突問題,僅僅一個noConflict是無法解決的)。另外,jqModal的作者如果看得懂我這篇文章估計也會對埋怨prototype,說:「我用for in對數組遍歷是不明智的,但是更該死的還是prototype。。」 

如上所述,如果你在用jqModal,同時因為別的原因在用prototype,恭喜你中招了。衝突將導致jqModal的彈框在ie6、ie7下面將無法利用closeClass設定的按鈕進行自動關閉。追蹤調試程式碼你將發現,異常的地方就在本文開頭提到的hs方法的for in 迴圈中。 。 。 
三,解問題 
遍歷陣列的地方,用for var 語句取代for in。

以上是javascript中for與for in區別,以及為什麼不建議使用for in的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn