【问题标题】:Any modern way to disable sort in Object.assign if objects has numeric keys?如果对象有数字键,有什么现代方法可以在 Object.assign 中禁用排序?
【发布时间】:2018-06-01 14:16:38
【问题描述】:

例如:snippet img

var a = {1: '1', 2: '2'}
var b = {3: '3', 4: '4'}

Object.assign({}, a, b)
> {1: "1", 2: "2", 3: "3", 4: "4"}

Object.assign({}, b, a)
> {1: "1", 2: "2", 3: "3", 4: "4"}

有没有办法禁用排序?

【问题讨论】:

  • 您应该考虑未排序的对象。你依赖事物的顺序,使用数组。
  • 对象属性没有顺序,那么“排序”是什么意思?
  • @Bergi:你知道这不再是真的了。 :-)(在实际使用中,即使是不需要遵循顺序的操作也在所有主要的 JavaScript 引擎上都这样做。)
  • @T.J.Crowder 在所有 JS 引擎上,但不是在所有 JS 转译器上
  • @slebetman:很好。与任何其他语言功能一样,如果为旧引擎进行转译,您需要了解可以和不可以填充或转换的内容。

标签: javascript ecmascript-6 ecmascript-5


【解决方案1】:

不,因为(如您所说)数字键(或使用规范的术语,整数索引*)。

Object.assign 按照[[OwnPropertyKeys]] 定义的顺序工作,对于普通对象来说是OrdinaryOwnPropertyKeys 抽象操作,它按照定义的顺序列出属性(首先是整数索引,然后是其他以字符串命名的属性)创建,然后是符号命名的属性(按创建顺序)。生成的对象的属性将以相同的方式枚举(通过遵循定义顺序的操作),因此,整数索引在数字上,然后是其他属性的创建顺序。

如果您的键不是整数索引,您可以通过按您想要的顺序预先创建属性来控制结果的顺序,但在整数索引键的情况下则不行。

因此,例如,如果您的键是 abcd,您可以确定结果对象属性的列出顺序(对于遵循该顺序的操作):

const x = {a: 'a', b: 'b'};
const y = {c: 'c', d: 'd'};
const result1 = Object.assign({c: null, d: null, a: null, b: null}, x, y);
console.log(JSON.stringify(result1));
const result2 = Object.assign({c: null, d: null, a: null, b: null}, y, x);
console.log(JSON.stringify(result2));
const result3 = Object.assign({a: null, b: null, c: null, d: null}, x, y);
console.log(JSON.stringify(result3));
const result4 = Object.assign({a: null, b: null, c: null, d: null}, y, x);
console.log(JSON.stringify(result4));

请注意,我在那里使用JSON.stringify 进行输出,因为JSON.stringify 被定义为遵循属性顺序(而for-inObject.keys 不是)。

但不适用于您的键,它们是整数索引。

如果顺序很重要,通常一个对象是错误的数据结构;相反,您需要一个数组。数组也是对象,数组的一些有序性只是约定(禁止优化),但它们具有几个重要的特定于顺序的特性,尤其是length 属性及其以定义顺序工作的各种方法。


*“整数索引”定义here:

整数索引是一个字符串值的属性键,它是一个规范的数字字符串(参见 7.1.16),其数值为 +0 或正整数 ≤ 253 -1.

【讨论】:

  • 感谢您的详细解答!我想我应该为我的案例使用一个额外的有序数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 2013-10-10
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
  • 2017-08-08
相关资源
最近更新 更多