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中文網其他相關文章!