JavaScript for...in 循环出来的对象属性顺序到底是什么规律?

在学习 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 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!