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

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

生成的对象总是这样吗?

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

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


当前回答

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

ECMAScript规范曾经说:

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

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

其他回答

来自JSON标准:

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

(强调我的)。

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

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

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

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

Object和MAP with Example的主要区别:

它是循环中的迭代顺序,在Map中它遵循创建时设置的顺序,而在OBJECT中没有。

看到的: 对象

const obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
obj['1'] = "day";
console.log(obj)

**OUTPUT: {1: "day", prop1: "Foo", prop2: "Bar"}**

MAP

    const myMap = new Map()
    // setting the values
    myMap.set("foo", "value associated with 'a string'")
    myMap.set("Bar", 'value associated with keyObj')
    myMap.set("1", 'value associated with keyFunc')

OUTPUT:
**1.    ▶0: Array[2]
1.   0: "foo"
2.   1: "value associated with 'a string'"
2.  ▶1: Array[2]
1.   0: "Bar"
2.   1: "value associated with keyObj"
3.  ▶2: Array[2]
1.   0: "1"
2.   1: "value associated with keyFunc"**

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

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

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

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

值得注意的是,在ES2015之前,对象中的属性顺序根本没有得到保证。ECMAScript第三版对象定义(pdf):

4.3.3对象 对象的成员 类型的对象。它是每个属性的无序集合 包含原语值、对象或 函数。函数中存储的函数 对象的属性称为 方法。

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

一般来说,没有

实际的问题非常模糊。

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

在什么情况下?

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

有时,是的

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

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类型,而不是普通的对象。