v8 - Object property ordering in javascript - Stack Overflow

I am trying to understand what's the thing with javascript Objects while using them as an associat

I am trying to understand what's the thing with javascript Objects while using them as an associative array.

From ECMA:

4.3.3 An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.

Using them in browser (chrome):

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}

While in the first example with the numbers as keys, they became ordered, in the second example with strings, they won't ( ordered = a,b,c ).

I am using these objects with string keys and I really don't want them to change order in some stage of app(if that's even possible) because it may crash the pipeline I am using.

Question is, is this approach safe and normal for every javascript machine, or should I use other method to guarantee that order won't ever change?

Thank you!

Edit: I am using this with node.js which runs on V8 (chrome engine), which 'orders non-numerical properties in insertion order'(Felix Kling). May this behaviour of V8 change?

I am trying to understand what's the thing with javascript Objects while using them as an associative array.

From ECMA:

4.3.3 An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.

Using them in browser (chrome):

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}

While in the first example with the numbers as keys, they became ordered, in the second example with strings, they won't ( ordered = a,b,c ).

I am using these objects with string keys and I really don't want them to change order in some stage of app(if that's even possible) because it may crash the pipeline I am using.

Question is, is this approach safe and normal for every javascript machine, or should I use other method to guarantee that order won't ever change?

Thank you!

Edit: I am using this with node.js which runs on V8 (chrome engine), which 'orders non-numerical properties in insertion order'(Felix Kling). May this behaviour of V8 change?

Share Improve this question edited Jan 12, 2015 at 16:59 petomalina asked Jan 12, 2015 at 16:48 petomalinapetomalina 2,1502 gold badges19 silver badges25 bronze badges 7
  • 7 Ordering of properties is undefined. That means that a JavaScript runtime is free to return the properties in any order it wants, and it doesn't even have to be the same order if you ask twice. You simply cannot rely on the ordering. If you need some fixed ordering put the property names in an array. – Pointy Commented Jan 12, 2015 at 16:50
  • 2 "should I use other method to guarantee that order won't ever change?" Yes. – j08691 Commented Jan 12, 2015 at 16:50
  • "It is an unordered collection" You can't rely on any order of object properties, the order can be whatever JS happens to give you. – Teemu Commented Jan 12, 2015 at 16:50
  • It is an unordered collection - This statement doesn't mean that the Javascript run-time is required preserve the order in which the properties were defined. It just means that you cannot rely on the ordering of properties to frame your logic! – jjk_charles Commented Jan 12, 2015 at 16:53
  • 1 Here is how Chrome is currently ordering the properties: Numerical properties e first in ascending order, then non-numerical properties in insertion order. This can change any time. – Felix Kling Commented Jan 12, 2015 at 16:54
 |  Show 2 more ments

4 Answers 4

Reset to default 6

Although Chrome may guarantee property order when using numbers as indexes in objects, the ECMA specification does not say it should do that, so by guarantee I'd not rely on this behavior. I suggest you to restructure your data to use arrays when you want to keep data order.

At the end of the day, it's because V8 uses if/else everywhere in the code to determine if it's an array index or an object property and not two separate classes to handle Array and Object separately like other JS engines:

https://lastzero/2009/09/object-property-ordering-in-google-chrome/

Yes, Google sticks to the specs, but it also makes it difficult to pass existing data structures from other programming languages to JS, because the ordering changes unexpectedly (even John Resig was surprised!). So you have to use different (possibly slower) data structures or use a converter, which makes code more plex.

It depends on the environment the code is running in, and the methods being used to iterate over the keys.

In ES5 and earlier, there is no defined order, regardless of the method used.

In ES6+, some methods which iterate over keys (but not all) are guaranteed to iterate in order over:

(1) increasing numeric keys (eg, 0, 1, 2), followed by

(2) non-numeric keys in insertion order, followed by

(3) symbols in insertion order.

The methods which are guaranteed to behave this way are, among others:

  • Reflect.ownKeys
  • Object.getOwnPropertyNames
  • Object.getOwnPropertySymbols
  • Object.defineProperties
  • Object rest/spread

These all invoke the internal method [[OwnPropertyKeys]], which guarantees the order.

Methods which are not guaranteed to iterate in any order, even in ES6+ environments, include:

  • for..in
  • Object.keys, Object.values, Object.entries
  • JSON.stringify

These methods all call EnumerateObjectProperties, which explicitly states:

The mechanics and order of enumerating the properties is not specified

All that said, even though order isn't guaranteed, in newer environments, the above methods will almost always iterate in the same deterministic order as Reflect.ownKeys anyway. Maybe you shouldn't depend on it, but it'll probably work, at least for now.

If you want a

method to guarantee that order won't ever change?

then to dependably iterate over an object, you should iterate using Reflect.ownKeys or Object.getOwnPropertyNames.

May this behaviour of V8 change?

If you use one of the methods guaranteed to iterate in a particular order, the behavior will not change, because Javascript pretty much always retains backwards patibility, and now that an required order has been described in the specification, no future changes will change that order.

I read from the spec.: Arrays are ordered, Objects not. Chrome seems to make no difference between number and string of numbers. (for performance reason?) I sometimes sidestep to an additional array of keys where needed.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742352816a4427852.html

相关推荐

  • v8 - Object property ordering in javascript - Stack Overflow

    I am trying to understand what's the thing with javascript Objects while using them as an associat

    7小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信