JavaScript是否保证对象属性顺序?
如果我创建这样的对象:JavaScript是否保证对象属性顺序?,javascript,object,Javascript,Object,如果我创建这样的对象: var obj = {}; obj.prop1 = "Foo"; obj.prop2 = "Bar"; 生成的对象总是这样吗 { prop1 : "Foo", prop2 : "Bar" } 也就是说,属性的顺序是否与我添加它们的顺序相同?在撰写本文时,大多数浏览器返回属性的顺序与插入属性的顺序相同,但这显然不能保证行为,因此不应依赖于此 过去人们常说: 枚举属性的机制和顺序。。。未指定 但是,在ES2015和更高版本中,非整数键将以插入顺序返回。对象的迭代顺序自ES
var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
生成的对象总是这样吗
{ prop1 : "Foo", prop2 : "Bar" }
也就是说,属性的顺序是否与我添加它们的顺序相同?在撰写本文时,大多数浏览器返回属性的顺序与插入属性的顺序相同,但这显然不能保证行为,因此不应依赖于此 过去人们常说: 枚举属性的机制和顺序。。。未指定
但是,在ES2015和更高版本中,非整数键将以插入顺序返回。对象的迭代顺序自ES2015以来一直遵循,但它(并不总是)遵循插入顺序。简单地说,迭代顺序是字符串键的插入顺序和数字键的升序的组合:
// key order: 1, foo, bar
const obj = { "foo": "foo", "1": "1", "bar": "bar" }
使用数组或数组可以更好地实现这一点<代码>地图与对象
有一些相似之处,毫无例外:
贴图中的键是有序的,而添加到对象中的键不是有序的。因此,当对其进行迭代时,贴图对象将按插入顺序返回关键帧。(请注意,在ECMAScript 2015规范中,对象确实保留了字符串和符号键的创建顺序,因此仅使用ie字符串键遍历对象将按插入顺序生成键)
请注意,在ES2015之前,对象中的属性顺序根本无法保证。对象的定义来自:
4.3.3目标
对象是
输入对象它是一个无序的属性集合每个属性
包含基元值、对象或
功能。存储在数据库中的函数
对象的属性称为
方法
从:
对象是零个或多个名称/值对的无序集合,其中名称是字符串,值是字符串、数字、布尔值、null、对象或数组
(我的重点)
因此,不,您不能保证顺序。是(对于非整数键)。
大多数浏览器将对象属性迭代为:
正如其他人所说,当您迭代对象的属性时,您无法保证顺序。如果需要多个字段的有序列表,我建议创建一个对象数组
var myarr = [{somfield1: 'x', somefield2: 'y'},
{somfield1: 'a', somefield2: 'b'},
{somfield1: 'i', somefield2: 'j'}];
通过这种方式,您可以使用常规for循环并具有插入顺序。然后,如果需要,您可以使用数组排序方法将其排序为新数组。在现代浏览器中,您可以使用
映射
数据结构而不是对象
贴图对象可以按插入顺序迭代其元素
整个答案是在符合规范的情况下给出的,而不是任何引擎在特定时刻或历史上所做的 一般来说,没有 实际问题非常模糊 属性的顺序是否与我添加它们的顺序相同 在什么情况下 答案是:这取决于许多因素。一般来说,没有 有时候,是的 这里是普通
对象的属性键顺序:
- 符合ES2015标准的发动机
- 自有财产
Object.getOwnPropertyNames()
,Reflect.ownKeys()
,Object.getOwnPropertySymbols(O)
在所有情况下,这些方法都包括由[[OwnPropertyKeys]]
指定的不可枚举的属性键和顺序键(见下文)。它们所包含的键值类型不同(String
和/或Symbol
)。在此上下文中,字符串
包括整数值
返回O
自己的String
键控属性(属性名称)
返回O
自己的String
-和Symbol
-键控属性
返回O
自己的Symbol
键控属性
顺序基本上是:按升序排列的整数类字符串
,按创建顺序排列的非整数类字符串
,按创建顺序排列的符号。根据调用此函数的函数,可能不包括其中的某些类型
特定语言是按以下顺序返回密钥:
。。。O
[正在迭代的对象]的每个属性键P
,都是整数索引,以升序数字索引顺序排列
。。。每个属性键Pconst o = Object.create(null, {
m: {value: function() {}, enumerable: true},
"2": {value: "2", enumerable: true},
"b": {value: "b", enumerable: true},
0: {value: 0, enumerable: true},
[Symbol()]: {value: "sym", enumerable: true},
"1": {value: "1", enumerable: true},
"a": {value: "a", enumerable: true},
});
Object {
0: 0,
1: "1",
2: "2",
b: "b",
a: "a",
m: function() {},
Symbol(): "sym"
}
const obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";
obj['1'] = "day";
console.log(obj)
**OUTPUT: {1: "day", prop1: "Foo", prop2: "Bar"}**
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"**