根据我的研究,钥匙在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
该键有数字排序(在所有Chrome,Firefox和边缘的)。为什么?
而且(因为我是错的)我怎么能透过他们通过.name
有序循环?
根据我的研究,钥匙在for..in循环顺序应该是不确定的/不可靠
未定义的,是的。
- 但是,如果不受干扰,应在插入顺序
不,你是正确的第一次:这不确定的。即使在ES2015(又名“ES6”)及以上,这确实提供了一些其他的操作特性秩序,旧业务for-in
和Object.keys
不需要遵循了新的定义的顺序。
在这些其它操作(Object.getOwnPropertyNames
,JSON.serialize
,...),顺序(defined here)不是纯粹的插入顺序:属性的名字是数组索引根据规范的定义*放在第一位,按数字顺序。大多数主要的JavaScript引擎已经更新了他们的for-in
的处理,以满足他们的这些新业务的处理(很多已经做了治疗数组索引不同,但他们在是否把那些非数组索引之前或之后方面差异),但同样,它是不确定的,你不应该依赖于它。
如果你想纯插入顺序,ES2015的Map
提供不论键的值。对象不。
下面是使用Map
一个例子:
const map = new Map([
['2', { name: 'bus', price: 10 }],
['3', { name: 'foot', price: 0 }],
['1', { name: 'taxi', price: 100 }]
]);
for (const entry of map.values()) { // bus, foot, taxi
console.log(entry.name);
}
*“阵列索引”的The spec's definition是:
的整数指数是一个字符串值属性密钥是一个规范的数字串(见7.1.16),并且其数字值是0或≤253-1的正整数。数组索引是一个整数指数,其数字值i的范围是从0≤I <232-1。
在实践中,javascript对象迭代通过在插入顺序键除了当键是数字。这可能是导致需要作出阵列迭代(数组是太对象)的键进行排序。
所以,你的选择是 - 尊重标准和使用ES6地图或对象的数组,以保证迭代顺序 - 让你的钥匙总是非数字和最好的希望