JavaScript 中的对象属性排序
Object property ordering in javascript
我试图理解javascript对象有什么问题,同时将它们用作关联数组。
来自ECMA:
4.3.3 对象是对象类型的成员。它是属性的无序集合,每个属性都包含一个基元 值、对象或函数。存储在 对象称为方法。
在浏览器(铬)中使用它们:
x = { 2: 'a', 3: 'b', 1: 'c' }
> Object {1: "c", 2: "a", 3: "b"}
y = { 'b': 2, 'c': 3, 'a': 1 }
> Object {b: 2, c: 3, a: 1}
在第一个示例中,数字作为键,它们是有序的,而在第二个字符串示例中,它们不会(有序 = a,b,c)。
我正在将这些对象与字符串键一起使用,我真的不希望它们在应用程序的某个阶段更改顺序(如果可能的话),因为它可能会使我正在使用的管道崩溃。
问题是,这种方法对于每台javascript机器来说都是安全和正常的,还是我应该使用其他方法来保证顺序永远不会改变?
谢谢!
编辑:我将其与node一起使用.js node在V8(chrome引擎)上运行,它"按插入顺序对非数字属性进行排序"(Felix Kling)。V8 的这种行为会改变吗?
尽管 Chrome 在对象中使用数字作为索引时可以保证属性顺序,但 ECMA 规范并没有说它应该这样做,因此通过保证,我不会依赖这种行为。我建议您在要保持数据顺序时重新构建数据以使用数组。
归根结底,这是因为 V8 在代码中的任何地方都使用 if/else 来确定它是数组索引还是对象属性,而不是像其他 JS 引擎那样分别处理数组和对象的两个单独的类:
https://lastzero.net/2009/09/object-property-ordering-in-google-chrome/
是的,Google坚持规范,但它也使得将现有数据结构从其他编程语言传递给JS变得困难,因为排序意外变化(甚至John Resig也很惊讶!因此,您必须使用不同的(可能更慢的)数据结构或使用转换器,这使得代码更加复杂。
这取决于代码运行的环境,以及用于迭代键的方法。
在 ES5 及更早版本中,无论使用哪种方法,都没有定义的顺序。
在 ES6+ 中,一些迭代键(但不是全部)的方法保证按顺序迭代:
(1)增加数字键(例如,0
,1
,2
),然后是
(2) 按插入顺序排列的非数字键,后跟
(3) 按插入顺序排列的符号。
保证以这种方式运行的方法包括:
-
Reflect.ownKeys
-
Object.getOwnPropertyNames
-
Object.getOwnPropertySymbols
-
Object.defineProperties
- 物体休息/展开
这些都调用了内部方法[[OwnPropertyKeys]]
,它保证了顺序。
即使在 ES6+ 环境中,也不能保证以任何顺序迭代的方法包括:
-
for..in
-
Object.keys
、Object.values
、Object.entries
-
JSON.stringify
这些方法都调用 EnumerateObjectProperties,它显式声明:
未指定枚举属性的机制和顺序
综上所述,即使不能保证顺序,但在较新的环境中,上述方法几乎总是以与Reflect.ownKeys
相同的确定性顺序进行迭代。也许你不应该依赖它,但它可能会起作用,至少目前是这样。
如果你想要一个
保证订单永远不会改变的方法?
然后,要可靠地迭代对象,您应该使用 Reflect.ownKeys
或 Object.getOwnPropertyNames
进行迭代。
V8 的这种行为会改变吗?
如果您使用保证按特定顺序迭代的方法之一,则行为不会改变,因为 Javascript 几乎总是保留向后兼容性,现在规范中已经描述了所需的顺序,将来的任何更改都不会更改该顺序。
我从规范中读到:数组是有序的,对象不是。 Chrome似乎在数字和数字字符串之间没有区别。(出于性能原因?我有时会在需要时避开额外的键数组。
- jQuery TinySort按数据属性排序和放置
- AngularJS使用对象属性排序多个对象数组
- JavaScript 中的对象属性排序
- 类型错误: 无法读取未定义的属性“排序级别”
- 按属性排序的 Javascript 对象数组不起作用
- 更改按自定义属性排序的对象数组的顺序
- JS mongoDB按previousItem属性排序(父子关系)
- 按ember.js对象控制器中的属性排序
- 按angularJS中的动态属性排序
- 在按导航属性排序时,breezejs:inlineCount不正确
- 按对象属性排序javascript数组
- 如何使用比较器按多个属性排序
- 基于任意长度的属性排序JavaScript对象数组
- 使用javascript按不同属性排序
- Jquery:按内部元素's属性排序
- 在Immutable.js的Map中,按子对象的属性排序的正确方法是什么?
- 基于日期属性排序javascript对象
- 使用NodeJS通过属性排序嵌套JSON
- 按类属性排序对象的树结构
- 使用jQuery UI Sortable交换数据属性排序