如果我创建一个这样的对象:
var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
生成的对象总是这样吗?
{ prop1 : "Foo", prop2 : "Bar" }
也就是说,属性是否与我添加它们的顺序相同?
如果我创建一个这样的对象:
var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
生成的对象总是这样吗?
{ prop1 : "Foo", prop2 : "Bar" }
也就是说,属性是否与我添加它们的顺序相同?
当前回答
在现代浏览器中,您可以使用Map数据结构而不是对象。
开发人员mozilla >地图
Map对象可以按插入顺序迭代其元素…
其他回答
整个答案是在规范遵从的背景下,而不是任何引擎在特定时刻或历史上所做的。
一般来说,没有
实际的问题非常模糊。
属性是否与我添加它们的顺序相同
在什么情况下?
答案是:这取决于许多因素。一般来说,没有。
有时,是的
在这里你可以指望属性键顺序为普通对象:
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类型,而不是普通的对象。
在现代浏览器中,您可以使用Map数据结构而不是对象。
开发人员mozilla >地图
Map对象可以按插入顺序迭代其元素…
这是我吃了不少苦头才知道的。
使用React和Redux,我想遍历的键的状态容器,以生成子,每次存储被更改时都会刷新(根据Redux的不变性概念)。
因此,为了获取Object.keys(valueFromStore),我使用了Object.keys(valueFromStore).sort(),这样我至少现在有了键的字母顺序。
正如其他人所述,当迭代对象的属性时,您无法保证顺序。如果你需要多个字段的有序列表,我建议创建一个对象数组。
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 ..循环不能保证按照规范的顺序。