如何摆脱数字属性的自动排序?

时间:2017-02-27 23:08:57

标签: javascript ecmascript-6 javascript-objects

我有一个对象newData,我在其中为其分配属性:

newData['5'] = 'test 1';
newData['3'] = 'test 2';
newData['8'] = 'test 3';

我明白了:

{
    '3': 'test 2',
    '5': 'test 1',
    '8': 'test 3'
}

但是我想保持属性的插入顺序,这就是我得到的:

{
    '5': 'test 1',
    '3': 'test 2',
    '8': 'test 3'
}

其中5,3和8按插入顺序排列。 JavaScript对象不应该有一个订单,但它显然会......而且这严重搞乱了循环。

我必须拥有密钥,因为JavaScript数组不支持自定义密钥,所以这需要是一个对象。如何添加到一个对象并保持它应该是无序的?

2 个答案:

答案 0 :(得分:4)

对象属性执行具有特定顺序,与插入顺序不同。它在ECMAScript 2015 Language Specification中描述:

  

9.1.12 [[OwnPropertyKeys]]()

     

当调用 O 的[[OwnPropertyKeys]]内部方法时,将采取以下步骤:

     
      
  1. 成为新的空List
  2.   
  3. 对于 O 的每个自己的property key P 是一个整数索引,升序数字索引顺序   
    一个。添加 P 作为键的最后一个元素
  4.   
  5. 对于属于字符串但不是整数索引的 O 的每个自己的property key P ,在属性创建顺序中   
    一个。添加 P 作为键的最后一个元素
  6.   
  7. 对于作为符号的 O 的每个自己的property key P ,在属性创建顺序中   
    一个。添加 P 作为键的最后一个元素
  8.   
  9. 返回
  10.   

在上面,属性被定义为List 。然后,当遇到属于整数的属性时,它将以升序数字顺序添加到List keys ,从而导致您观察到3,5,8。

如果您想要基于插入而遵守顺序的有序键和值对,则必须使用符合顺序的内容,例如ES6 Map。根据文件:

  

Map对象按插入顺序迭代其元素 - for...of循环为每次迭代返回一个[key, value]数组。

以下是一个例子:

const obj = new Map([
  [5, "test 1"],
  [3, "test 2"],
  [8, "test 3"]
]);

for(let [key, value] of obj) {
  console.log(key, value);
}

首先,将数组数组传递给构造函数。 Map构造函数接受一个iterable,并使用子数组作为键和值对。 Map基本上如下所示:

+-----+----------+
| Key | Value    |
+-----+----------+
|  5  | "test 1" |
|  3  | "test 2" |
|  8  | "test 3" |
+-----+----------+

接下来,使用for...of循环迭代Map。如文档中所述,迭代器返回[key, value]数组,因此您可以使用array destructuring。因此,keyvalue分别保存Map的键值和值,并记录它们提供所需的有序结果。

答案 1 :(得分:0)

您可以查看Map。它尊重基于插入顺序的遍历。