Javascript學習筆記之 對象篇(四) : for in 循環(huán)
先上范例:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // prints both bar and moo }
這里我們要注意兩點,一是 for in 循環(huán)會忽略 enumerable 設置為 false 的屬性。例如一個數(shù)組的 length 屬性。第二是,由于 for in 會遍歷整個原型鏈,所以當原型鏈過長時,會對性能造成影響。
enumerable 是個很陌生的詞匯,實際上,你很難在 javascript 中發(fā)現(xiàn)它的影子,而它實際上也是作者從 ruby 中借鑒而來的。創(chuàng)建 enumerable 的目的不是為了獨立使用,而是采用“混用”的方式,而 Prototype 中很多方法都混用了 enumerable,所以它可以說是 prototype 的奠基石。這里不做詳細介紹,詳細內(nèi)容可以參考 - Enumerable。
由于我們沒法改變 for in 循環(huán)本身的行為,所以我們只能采取其他方法來過濾掉那些不希望出現(xiàn)在循環(huán)內(nèi)的屬性,通過 《Javascript學習筆記之對象篇(三) : hasOwnProperty》 我們知道 hasOwnProperty 方法是可以做到這一點的。
使用 hasOwnProperty 過濾
仍然使用上個例子:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } }
這是唯一正確的寫法,由于我們實用了 hasOwnProperty 方法,所以這次只輸出 moo。如果不適用 hasOwnProperty 方法,那么當 Object.prototype 擴展時,就會出現(xiàn)錯誤。
現(xiàn)在很多框架都會選擇從 Object.prototype 擴展方法,所以我們使用這些框架時,如果使用沒有用 hasOwnProperty 過濾的 for in 循環(huán)時就會遇到問題。
總結
建議養(yǎng)成 hasOwnProperty 過濾屬性的好習慣,不要對運行環(huán)境做任何假設,也無論原生的原型對象是否被擴展。
相關文章
javascript 學習筆記(八)javascript對象
昨天看了些有關javascript對象方面的文章,以下是自己的一些學習心得及體會,希望同大家共同討論!2011-04-04javascript學習筆記(十九) 節(jié)點的操作實現(xiàn)代碼
javascript學習筆記之節(jié)點的操作實現(xiàn)代碼,包括節(jié)點的創(chuàng)建、添加、移除、替換、復制2012-06-06Javascript基礎教程之數(shù)據(jù)類型轉換
JavaScript是一種無類型語言,但同時JavaScript提供了一種靈活的自動類型轉換的處理方式?;疽?guī)則是,如果某個類型的值用于需要其他類型的值的環(huán)境中,JavaScript就自動將這個值轉換成所需要的類型。2015-01-01