如果我创建一个这样的对象:

var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";

生成的对象总是这样吗?

{ prop1 : "Foo", prop2 : "Bar" }

也就是说,属性是否与我添加它们的顺序相同?


当前回答

正如其他人所述,当迭代对象的属性时,您无法保证顺序。如果你需要多个字段的有序列表,我建议创建一个对象数组。

var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];

这样你就可以使用一个常规的for循环,并有插入顺序。然后,如果需要,可以使用Array sort方法将其排序到一个新数组中。

其他回答

这是我吃了不少苦头才知道的。

使用React和Redux,我想遍历的键的状态容器,以生成子,每次存储被更改时都会刷新(根据Redux的不变性概念)。

因此,为了获取Object.keys(valueFromStore),我使用了Object.keys(valueFromStore).sort(),这样我至少现在有了键的字母顺序。

在撰写本文时,大多数浏览器确实以插入属性的相同顺序返回属性,但这显然不能保证行为,因此不应该依赖。

ECMAScript规范曾经说:

列举属性的机制和顺序……未指定。

但是在ES2015及以后版本中,非整数键将按插入顺序返回。

从ES2015开始,对于迭代属性的某些方法,属性顺序得到了保证。但其他人不是。不幸的是,不保证有顺序的方法通常是最常用的:

对象。钥匙,对象。值,Object.entries 在循环. . JSON.stringify

但是,从ES2020开始,这些以前不值得信任的方法的属性顺序将由规范保证,以与其他方法相同的确定性方式迭代,这是由于完成的提议:for-in机制。

就像有保证迭代顺序的方法一样(比如Reflect。ownKeys和Object.getOwnPropertyNames),之前未指定的方法也将按以下顺序迭代:

数值数组键,按升序排列 所有其他非符号键,按插入顺序 符号键,按插入顺序

这是几乎每个实现都已经在做的事情(并且已经做了很多年),但是新提案将其正式化。

虽然目前的规范在迭代顺序中留下了..,但“几乎完全不确定,真正的引擎往往更一致:”

ECMA-262缺乏特异性并不能反映现实。在几年前的讨论中,实现者已经注意到for-in的行为有一些约束,任何想要在web上运行代码的人都需要遵循这些约束。

因为每个实现都已可预测地遍历属性,所以可以在不破坏向后兼容性的情况下将其放入规范中。


有一些奇怪的情况,实现目前没有达成一致,在这种情况下,结果的顺序将继续未指定。财产顺序担保:

Neither the object being iterated nor anything in its prototype chain is a proxy, typed array, module namespace object, or host exotic object. Neither the object nor anything in its prototype chain has its prototype change during iteration. Neither the object nor anything in its prototype chain has a property deleted during iteration. Nothing in the object's prototype chain has a property added during iteration. No property of the object or anything in its prototype chain has its enumerability change during iteration. No non-enumerable property shadows an enumerable one.

在现代浏览器中,您可以使用Map数据结构而不是对象。

开发人员mozilla >地图

Map对象可以按插入顺序迭代其元素…

在ES2015中,确实如此,但不是你想的那样

对象中键的顺序直到ES2015才得到保证。它是由实现定义的。

但是,在ES2015中指定了in。像JavaScript中的许多东西一样,这样做是为了兼容性,并且通常反映了大多数JS引擎中现有的非官方标准(你知道谁是例外)。

该顺序在规范中定义,在抽象操作OrdinaryOwnPropertyKeys下,该操作支持遍历对象自身键的所有方法。转述一下,顺序如下:

所有整数索引键(像“1123”,“55”等)以升序数字排列。 所有不是整数索引的字符串键,按创建的顺序(最早的-先的)。 所有符号键,按创建的顺序(最早的-先的)。

说顺序不可靠是愚蠢的——它是可靠的,只是可能不是你想要的,现代浏览器正确地实现了这个顺序。

一些例外包括枚举继承键的方法,例如for ..在循环。for ..循环不能保证按照规范的顺序。