1

According to Elements order in a "for (… in …)" loop, I know javascript objects have no defined order currently, but my question is, suppose I iterate the same object 2 times, eg:

var obj = {
  "a":1,
  "b":2,
};

for (var i in obj){
  //very random order 1
};

//some other code

for (var i in obj){
  //very random order 2
};

is "very random order 1" always the same as "very random order 2"?

ocomfd
  • 4,010
  • 2
  • 10
  • 19
  • 1
    It may. It may not. Even if it does, it's an implementation detail that can change in another browser, or even in another version of your browser. – spectras Aug 01 '18 at 09:37
  • According to answer in question you linked, order is NOT random – ponury-kostek Aug 01 '18 at 09:37
  • The order is by no means random, it's just hidden by the implementation. There are no guarantees of the order of results and as such should not be depended upon. – phuzi Aug 01 '18 at 09:41
  • Check out https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of, "Difference between for...of and for...in": "The for...in statement iterates over the enumerable properties of an object, in an arbitrary order." So yes, it's arbitrary. – fjc Aug 01 '18 at 09:50
  • Possible duplicate of [Elements order in a "for (… in …)" loop](https://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop) – ponury-kostek Aug 01 '18 at 10:57

2 Answers2

0

It's an implementation detail, so you can't really be sure unless you actually look at the implementation, and then it might still change between browsers or versions.

But my guess would be that the order remains the same at least if the object remains unchanged in the mean time. The reason for that being that there is some dictionary of properties, and as long as you don't mess around in that dictionary there wouldn't be a reason for it to return a different order. The order is not actually random, it's just not officially sorted in any particular way. So it's undefined rather than random.

Then again, as the answer you linked to mentions as well, the behavior is explicitly undefined, so don't rely on it. If you need a particular sorting, make it so instead of relying on undocumented implementation details.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
0

The keys should always come in the same order, but if it is an issue you could fetch and/or sort the keys individually and then access the data:

function getOwnKeys(obj) {
  return Object
    .keys(obj)
    .filter(function(a) {
      return obj.hasOwnProperty(a);
    });
}
var obj = {
  b: 2,
  a: 1,
  c: 3
};
//Classic way
console.log("Classic way");
for (var key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}
//Getting (and sorting) the keys
console.log("Getting (and sorting) the keys");
var keys = getOwnKeys(obj).sort();
for (var keyIndex = 0; keyIndex < keys.length; keyIndex++) {
  var key = keys[keyIndex];
  console.log(key, obj[key]);
}

As noted in the comments by fjc in this comment, this MDN page specifies that:

The for...in statement iterates over the enumerable properties of an object, in an arbitrary order.

And further down:

This loop logs only enumerable properties of iterable object, in original insertion order.

This is of course Mozilla Firefoxs current implementation, so it could very well be different in other browsers or even in older versions of Mozilla Firefox.

Emil S. Jørgensen
  • 6,216
  • 1
  • 15
  • 28
  • They might come in a certain order in current implementations, but it is not guaranteed: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of – fjc Aug 01 '18 at 09:52