我知道JS对象不保证密钥顺序,但是,我的数据结构来自我无法控制的后端。从以下地方开始,我可以做些什么来保存关键顺序:
var obj = {
foo: 'bar',
bar: 'foo'
};
为:
Object.keys(obj); // hoping for ['foo', 'bar']
最重要的是,我不幸地保留了关键顺序......
答案 0 :(得分:4)
没有。正如你写的那样:
我知道JS对象中没有保证关键顺序
如果您需要订单,则需要使用数组。如果您有一个对象,则属性没有已定义的顺序。
答案 1 :(得分:1)
ECMA-262
未指定枚举顺序。事实上的标准是匹配插入顺序。
虽然对数组索引的枚举顺序(即,可以解析为integer
的属性名称)没有给出任何保证,因为数组索引的插入顺序会产生大量内存
开销。
编辑: 添加了jsfiddle example。
var obj1 = {
a: 'test1',
b: 'test2'
};
var obj2 = {
2: 'test1',
1: 'test2'
};
// max 32bit unsigned is 2,147,483,647
var obj3 = {
2147483649: 'test1',
2147483648: 'test2'
};
// max 64bit unsigned is 9,223,372,036,854,775,807
var obj4 = {
9223372036854770: 'test1',
9223372036854768: 'test2',
};
// != number < 2,147,483,647, order is not changed
console.log(Object.keys(obj1));
// < 2,147,483,647, order is changed
console.log(Object.keys(obj2));
// > 2,147,483,647, order is not changed in Firefox, but changed in Chrome
console.log(Object.keys(obj3));
// > 9,223,372,036,854,775,807, order is not changed in neither Firefox or Chrome
console.log(Object.keys(obj4));
这意味着Chrome的javascript
引擎V8
会订购任何64bit unsigned
个号码,而Firefox的javascript
引擎SpiderMonkey
会订购任何32bit unsigned
个数字。
答案 2 :(得分:1)
对象是零个或多个名称/值对的无序集合...
严格来说,文字JSON文本当然有一个顺序:文本不会突然自我扰乱。但是,您希望的行为 - 一组有序的名称/值对 - 不是JSON提供的构造。您希望对象表示法提供超出JSON规范所要求的语义的语义含义。
顺便说一下,在JSON中执行此操作
{
"foo": "baz",
"bar": "egg"
}
是无序集的描述。如果您打算用它来描述有序集,那么您就不会遵循JSON规则。数据恰好是有序的(因为这就是字符序列的工作原理),但是当考虑输入字符串中存在的数据时,JSON语义可以自由地允许实现完全忽略名称/值对的顺序。
您可以编写直接在JSON输入字符串上运行的代码,以便以某种方式解析键的输入顺序来解析文本,但不需要JSON解析器实现来为您提供该功能。
正确的JSON-idiomatic解决方案是在JSON响应中提供一组键名:
{
data: {
"foo": "baz",
"bar": "egg"
},
order: ["foo", "bar"]
}
显然,如果您不控制响应,则不能这样做。通过选择表示对象中的数据,响应的作者断言键的顺序纯粹是任意的。如果JSON的作者打算断言密钥条目的顺序,那么该断言是JSON规则的外部。
实际上,大多数JavaScript引擎通常会选择按照其属性的创建顺序报告密钥名称。但是,任何规范都不要求这种行为(并且在边缘情况下有时不一致),因此引擎和版本之间在法律上可能不同。