for.in–的迭代顺序; 不是通过插入(更多?)

T4N*_*K3R 6 javascript sorting for-in-loop

根据我的研究,for..in循环中键的顺序应该是未定义/不可靠的 - 但是,如果不受干扰,应该按插入顺序 - 但它不是:

我从数据库中获取此数据对象,按名称排序:

var travel = {  
    '2': { name: 'bus',  price: 10 },  
    '3': { name: 'foot', price: 0 },  
    '1': { name: 'taxi', price: 100 }  
}  
for (way in travel) console.log( travel[way].name ) // => taxi, bus, foot  
Run Code Online (Sandbox Code Playgroud)

密钥以数字方式排序(在Chrome,Firefox和Edge中).为什么?

并且(因为我错了)我怎么能按顺序遍历它们.name

T.J*_*der 3

\n

根据我的研究, for..in 循环中的键顺序应该是未定义/不可靠的

\n
\n\n

未定义,是的。

\n\n
\n
    \n
  • 但是,如果不受影响,则应按插入顺序排列
  • \n
\n
\n\n

不,你第一次是对的:它是未定义的。即使在 ES2015(又名“ES6”)及更高版本中,它们确实为某些其他操作提供了属性顺序,for-in但旧操作Object.keys也不需要遵循为新操作定义的顺序。

\n\n

在那些其他操作(Object.getOwnPropertyNamesJSON.serialize、 ...)中,顺序(此处定义)并非纯粹的插入顺序:名称为数组索引(根据规范的定义*)的属性首先按数字顺序排列。大多数主要的 JavaScript 引擎都更新了它们的处理方式,for-in以匹配它们对这些新操作的处理(许多引擎已经以不同的方式对待数组索引,但它们在将它们放在非数组索引之前还是之后有所不同),但同样,它是未定义的,您不应该依赖它。

\n\n

如果你想要纯粹的插入顺序,ES2015Map提供了这一点,无论键的值是什么。对象则不然。

\n\n

这是一个使用的示例Map

\n\n

\r\n
\r\n
const map = new Map([\r\n  [\'2\', { name: \'bus\',  price: 10 }],\r\n  [\'3\', { name: \'foot\', price: 0 }],\r\n  [\'1\', { name: \'taxi\', price: 100 }]\r\n]);\r\nfor (const entry of map.values()) { // bus, foot, taxi\r\n  console.log(entry.name);\r\n}
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n


\n\n

*规范对“数组索引”的定义是:

\n\n
\n

整数索引是一个字符串值属性键,它是一个规范的数字字符串(请参阅 7.1.16),其数值为 +0 或正整数 \xe2\x89\xa4 2 53-1数组索引是一个整数索引,其数值i的范围为 +0 \xe2\x89\xa4 i < 2 32-1

\n
\n