JavaScript for...in 迴圈出來的物件屬性順序到底是什麼規律?

zhangbao發表於2018-01-25

在學習 JavaScript 語言的 for...in 迴圈時,總是會被告知:用它迴圈物件,迴圈出來的屬性順序並不可靠,所以不要在 for...in 中做依賴物件屬性順序的邏輯判斷。

但是我們自己寫一個物件時,來回重新整理好幾遍,發現迴圈出來的屬性順序是一樣的啊?

let user = {
  name: "John",
  age: 30,
  isAdmin: true
};

for(let key in user) {
  console.log( key ); // name age isAdmin ← 是一樣的啊
}

// 不信再寫一個物件
let tom = {
  gender: 'male',
  hasGirlfriend: false,
  isFunny: true
};

for(let key in tom) {
  console.log( key ); // gender hasGirlfriend isFunny ← 還是一樣的啊
}

怎麼回事呢?我今天讀到了 一段文章,就解釋了 for...in 迴圈出來的物件屬性順序到底是怎樣的。

讀後,我明白了。現在分享給大家。

簡單歸結成一句話就是:先遍歷出整數屬性(integer properties,按照升序),然後其他屬性按照建立時候的順序遍歷出來

我們來看一個例子:

let codes = {
  "49": "Germany",
  "41": "Switzerland",
  "44": "Great Britain",
  "1": "USA"
};

for(let code in codes) {
  alert(code); // 1, 41, 44, 49
}

最終遍歷出來的結果是:屬性 1 先遍歷出來, 49 最後遍歷出來。

這裡的 1414449 就是整數屬性。

那什麼是整數屬性呢?我們可以用下面的比較結果說明:

String(Math.trunc(Number(prop)) === prop

當上面的判斷結果為 true,prop 就是整數屬性,否則不是。

所以

  • "49" 是整數屬性,因為 String(Math.trunc(Number('49')) 的結果還是 "49"
  • "+49" 不是整數屬性,因為 String(Math.trunc(Number('+49')) 的結果是 "49",不是 "+49"
  • "1.2" 不是整數屬性,因為 String(Math.trunc(Number('1.2')) 的結果是 "1",不是 "1.2"

上面的例子中,如果想按照建立順序迴圈出來,可以用一個 討巧 的方法:

let codes = {
  "+49": "Germany",
  "+41": "Switzerland",
  "+44": "Great Britain",
  // ..,
  "+1": "USA"
};

for(let code in codes) {
  console.log( +code ); // 49, 41, 44, 1
}

(完)

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章