JavaScript探秘:for-in循環(for-in Loops)

使用for-in進行循環也被稱為“枚舉”
服務器君一共花費了173.991 ms進行了6次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

for-in循環應該用在非數組對象的遍歷上,使用for-in進行循環也被稱為“枚舉”。

從技術上將,你可以使用for-in循環數組(因為JavaScript中數組也是對象),但這是不推薦的。因為如果數組對象已被自定義的功能增強,就可能發生邏輯錯誤。另外,在for-in中,屬性列表的順序(序列)是不能保證的。所以最好數組使用正常的for循環,對象使用for-in循環。

有個很重要的hasOwnProperty()方法,當遍歷對象屬性的時候可以過濾掉從原型鏈上下來的屬性。

思考下面一段代碼:

// 對象
var man = {
   hands: 2,
   legs: 2,
   heads: 1
};

// 在代碼的某個地方
// 一個方法添加給了所有對象
if (typeof Object.prototype.clone === "undefined") {
   Object.prototype.clone = function () {};
}

在這個例子中,我們有一個使用對象字面量定義的名叫man的對象。在man定義完成后的某個地方,在對象原型上增加了一個很有用的名叫 clone()的方法。此原型鏈是實時的,這就意味著所有的對象自動可以訪問新的方法。為了避免枚舉man的時候出現clone()方法,你需要應用hasOwnProperty()方法過濾原型屬性。如果不做過濾,會導致clone()函數顯示出來,在大多數情況下這是不希望出現的。

// 1.
// for-in 循環
for (var i in man) {
   if (man.hasOwnProperty(i)) { // 過濾
      console.log(i, ":", man[i]);
   }
}
/* 控制臺顯示結果
hands : 2
legs : 2
heads : 1
*/

// 2.
// 反面例子:
// for-in loop without checking hasOwnProperty()
for (var i in man) {
   console.log(i, ":", man[i]);
}
/*
控制臺顯示結果
hands : 2
legs : 2
heads : 1
clone: function()
*/

另外一種使用hasOwnProperty()的形式是取消Object.prototype上的方法。像這樣:

for (var i in man) {
   if (Object.prototype.hasOwnProperty.call(man, i)) { // 過濾
      console.log(i, ":", man[i]);
   }
}

其好處在于在man對象重新定義hasOwnProperty情況下避免命名沖突。也避免了長屬性查找對象的所有方法,你可以使用局部變量“緩存”它。

var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
    if (hasOwn.call(man, i)) { // 過濾
        console.log(i, ":", man[i]);
    }
}

嚴格來說,不使用hasOwnProperty()并不是一個錯誤。根據任務以及你對代碼的自信程度,你可以跳過它以提高些許的循環速度。但是當你對當前對象內容(和其原型鏈)不確定的時候,添加hasOwnProperty()更加保險些。

格式化的變化(通不過JSLint)會直接忽略掉花括號,把if語句放到同一行上。其優點在于循環語句讀起來就像一個完整的想法(每個元素都有一個自己的屬性”X”,使用”X”干點什么):

// 警告: 通不過JSLint檢測
var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) if (hasOwn.call(man, i)) { // 過濾
    console.log(i, ":", man[i]);
}

延伸閱讀

此文章所在專題列表如下:

  1. 我們應該如何去了解JavaScript引擎的工作原理
  2. JavaScript探秘:編寫可維護的代碼的重要性
  3. JavaScript探秘:謹慎使用全局變量
  4. JavaScript探秘:var預解析與副作用
  5. JavaScript探秘:for循環(for Loops)
  6. JavaScript探秘:for-in循環(for-in Loops)
  7. JavaScript探秘:Prototypes強大過頭了
  8. JavaScript探秘:eval()是“魔鬼”
  9. JavaScript探秘:用parseInt()進行數值轉換
  10. JavaScript探秘:基本編碼規范
  11. JavaScript探秘:函數聲明與函數表達式
  12. JavaScript探秘:命名函數表達式
  13. JavaScript探秘:調試器中的函數名
  14. JavaScript探秘:JScript的Bug
  15. JavaScript探秘:JScript的內存管理
  16. JavaScript探秘:SpiderMonkey的怪癖
  17. JavaScript探秘:命名函數表達式替代方案
  18. JavaScript探秘:對象Object
  19. JavaScript探秘:原型鏈 Prototype chain
  20. JavaScript探秘:構造函數 Constructor
  21. JavaScript探秘:可執行的上下文堆棧
  22. 執行上下文其一:變量對象與活動對象
  23. 執行上下文其二:作用域鏈 Scope Chains
  24. 執行上下文其三:閉包 Closures
  25. 執行上下文其四:This指針
  26. JavaScript探秘:強大的原型和原型鏈
  27. JavaScript函數其一:函數聲明
  28. JavaScript函數其二:函數表達式
  29. JavaScript函數其三:分組中的函數表達式
  30. JavaScript函數其四:函數構造器
  31. JavaScript變量對象其一:VO的聲明
  32. JavaScript變量對象其二:VO在不同的執行上下文中
  33. JavaScript變量對象其三:執行上下文的兩個階段
  34. JavaScript變量對象其四:關于變量
  35. JavaScript變量對象其五:__parent__ 屬性
  36. JavaScript作用域鏈其一:作用域鏈定義
  37. JavaScript作用域鏈其二:函數的生命周期
  38. JavaScript作用域鏈其三:作用域鏈特征
  39. JavaScript閉包其一:閉包概論
  40. JavaScript閉包其二:閉包的實現
  41. JavaScript閉包其三:閉包的用法

本文地址:http://www.zqhthc.tw/librarys/veda/detail/1625,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.zqhthc.tw/librarys/veda/detail/1625

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《設計模式:可復用面向對象軟件的基礎》 Erich Gamma (作者), Richard Helm (作者), Ralph Johnson (作者), John Vlissides (作者), 李英軍 (譯者), 等 (譯者)

《設計模式:可復用面向對象軟件的基礎》是引導讀者走出軟件設計迷宮的指路明燈,凝聚了軟件開發界幾十年設計經驗的結晶。四位頂尖的面向對象領域專家精心選取了最具價值的設計實踐,加以分類整理和命名,并用簡潔而易于重用的形式表達出來。本書已經成為面向對象技術人員的圣經和詞典,書中定義的23個模式逐漸成為開發界技術交流所必備的基礎知識和語匯。

更多計算機寶庫...

英超直播吻球网