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

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

生成的对象总是这样吗?

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

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


当前回答

对于一个100%故障安全的解决方案,你可以使用嵌套对象,并像这样做:

const obj = {};
obj.prop1 = {content: "Foo", index: 0};
obj.prop2 = {content: "Bar", index: 1};

for (let i = 0; i < Object.keys(obj).length; i++)
for (const prop in obj) {
    if (obj[prop].index == i) {
        console.log(obj[prop].content);
        break;
    }
}

其他回答

是(但不总是插入顺序)。

大多数浏览器迭代对象属性为:

以升序排列的正整数键(以及像“1”这样解析为整型的字符串) 字符串键,按插入顺序(ES2015保证这一点,所有浏览器都遵守) 符号名称,按插入顺序(ES2015保证这一点,所有浏览器都遵守)

一些较老的浏览器结合了类别#1和#2,按插入顺序迭代所有键。如果您的键可能被解析为整数,最好不要依赖于任何特定的迭代顺序。

当前语言规范(自ES2015起)的插入顺序保持不变,除非键解析为正整数(如“7”或“99”),在不同浏览器中行为不同。例如,当键被解析为数字时,Chrome/V8不尊重插入顺序。

旧的语言规范(在ES2015之前):迭代顺序在技术上没有定义,但所有主流浏览器都遵守ES2015行为。

请注意,ES2015行为是语言规范由现有行为驱动的一个很好的例子,而不是相反。要更深入地了解向后兼容的心态,请参阅http://code.google.com/p/v8/issues/detail?id=164,这是一个Chrome bug,详细介绍了Chrome迭代顺序行为背后的设计决策。 根据对该错误报告的(相当固执己见的)评论:

标准总是跟着实现走的,XHR就是这么来的,谷歌通过实现Gears,然后拥抱等价的HTML5功能来做同样的事情。正确的解决方法是让ECMA正式地将事实上的标准行为纳入规范的下一个版本中。

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

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

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

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

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

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

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

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

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

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

整个答案是在规范遵从的背景下,而不是任何引擎在特定时刻或历史上所做的。

一般来说,没有

实际的问题非常模糊。

属性是否与我添加它们的顺序相同

在什么情况下?

答案是:这取决于许多因素。一般来说,没有。

有时,是的

在这里你可以指望属性键顺序为普通对象:

ES2015兼容引擎 自己的属性 Object.getOwnPropertyNames(), Reflect.ownKeys(), Object.getOwnPropertySymbols(O)

在所有情况下,这些方法都包括不可枚举的属性键和由[[OwnPropertyKeys]]指定的顺序键(见下文)。它们所包含的键值类型不同(字符串和/或符号)。在这个上下文中,String包含整数值。

Object.getOwnPropertyNames (O)

返回O自己的string键属性(属性名)。

Reflect.ownKeys (O)

返回O自己的字符串和符号键属性。

Object.getOwnPropertySymbols (O)

返回O自己的符号键属性。

[OwnPropertyKeys]

顺序基本上是:类整数的字符串按升序排列,非类整数的字符串按创建顺序排列,符号按创建顺序排列。根据调用该函数的函数,其中一些类型可能不包括在内。

具体的语言是键按以下顺序返回:

... 每个属性键P of O[被迭代的对象]是一个整数索引,按升序数字索引 ... 每个属性键P (O)都是一个字符串,但不是一个整数索引,按属性创建顺序 ... 每个人都拥有属性键P (O),这是一个符号,按属性创建顺序

Map

如果你对有序映射感兴趣,你应该考虑使用ES2015中引入的Map类型,而不是普通的对象。

来自JSON标准:

对象是零个或多个名称/值对的无序集合,其中名称为字符串,值为字符串、数字、布尔值、空值、对象或数组。

(强调我的)。

所以,不,你不能保证订单。