JavaScript 是否保证对象属性顺序?

新手上路,请多包涵

如果我创建这样的对象:

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

生成的对象会 总是 这样吗?

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

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

原文由 mellowsoon 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

自 ES2015 以来,对象的迭代顺序遵循 一组特定的规则,但 它并不(总是)遵循插入顺序。简单地说,迭代顺序是字符串键的插入顺序和数字键的升序的组合:

 // key order: 1, foo, bar
 const obj = { "foo": "foo", "1": "1", "bar": "bar" }

使用数组或 Map 对象 可能是实现此目的的更好方法。 MapObject 有一些相似之处,并 保证键按插入顺序迭代,无一例外:

Map 中的键是有序的,而添加到对象的键不是。因此,在对其进行迭代时, Map 对象会按插入顺序返回键。 (请注意,在 ECMAScript 2015 规范中,对象确实保留了字符串和符号键的创建顺序,因此仅使用字符串键遍历对象将按插入顺序生成键)

请注意,在 ES2015 之前,对象中的属性顺序根本无法保证。 ECMAScript 第三版中的对象定义(pdf)

4.3.3 对象

对象是

类型对象。 它是一个无序的属性集合, 每个属性

包含原始值、对象或

功能。存储在一个函数

对象的属性称为

方法。

原文由 bpierre 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

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

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

保留 当前语言规范(自 ES2015 起) 的插入顺序,但解析为正整数(例如“7”或“99”)的键除外,其行为因浏览器而异。例如,当键被解析为数字时,Chrome/V8 不遵守插入顺序。

旧语言规范(ES2015 之前) :迭代顺序在技术上未定义,但所有主要浏览器都符合 ES2015 行为。

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

标准总是遵循实现,这就是 XHR 的来源,Google 通过实现 Gears 然后采用等效的 HTML5 功能来做同样的事情。正确的解决方法是让 ECMA 将事实上的标准行为正式合并到规范的下一个版本中。

原文由 Dave Dopson 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题