5

This question is vital to one of my current projects involving creating HTML tables from JSON objects. I was thinking I could create functions that would sort my Arrays/Objects before rendering them as HTML. My only concern is that order doesn't matter in JavaScript, and if I were to create a new Array with the same data (in a different order) as another Array they would end up identical.

I can't think of a fast way to test this, so I'm asking here.

Hubro
  • 48,322
  • 60
  • 196
  • 344
  • Mongo, the javascript shell for MongoDB, currently uses object set order to define sorts. I wondered if this was correct, and wound up testing a bit in nodejs and looking here.... Apparently it is, sorta. See "$sort" in http://docs.mongodb.org/manual/reference/aggregation/ – Paul May 11 '13 at 03:11

5 Answers5

9

Others have answered on arrays, so I just wanted to provide some info on objects.

On that, the standard is non-existent, but it's de facto definition is that an object will enumerate in insertion order, with the exception that numbers are placed in ascending order and enumerated first. I say typically, but this behavior is nowhere near standardized (nor do frameworks like jQuery standardize it, AFAIK).

You can test browsers using this jsFiddle:

http://jsfiddle.net/7cCpu/4/

The object {"foo":"bar", "bar":"foo", "baz":"baz", "3":3, "2":2, "1":1} enumerates as follows:

foo, bar, baz, 3, 2, 1 // insertion order

1, 2, 3, foo, bar, baz // Chrome enumeration
1, 2, 3, foo, bar, baz // Opera
1, 2, 3, foo, bar, baz // IE9
foo, bar, baz, 3, 2, 1 // Firefox (!!!)

I don't have Safari installed, but I assume it's the same as Chrome. In any case, the point is that you can make assumptions -- it's not random -- but it's probably a better idea to use an array if you depend on exact enumeration.

Even nastier is what duri pointed out above, where deleting and replacing the value for a key alters things further. Watch what happens when I delete bar and do Object.bar = "foo" then enumerate:

1, 2, 3, foo, baz, bar // Chrome enumeration
1, 2, 3, foo, baz, bar // Opera
1, 2, 3, foo, bar, baz // IE9 (!!!)
foo, baz, 3, 2, 1, bar // Firefox (!!!)
brymck
  • 7,216
  • 25
  • 30
5

Arrays are enumerated by (numeric) index.

Objects aren't - the order isn't defined, indeed the Javascript standards explicity state that the order is undefined. For more detail see Does JavaScript Guarantee Object Property Order?

Community
  • 1
  • 1
Alnitak
  • 313,276
  • 69
  • 379
  • 466
2

Good example when order of object properties differs is this code:

var o = { foo: 1, bar: 2, baz: 3 };
delete o.bar;
o.bar = 2;
for (var i in o)    {
    document.write(o[i]);
}

This displays 132 in Firefox, but 123 in Internet Explorer.

duri
  • 13,813
  • 3
  • 41
  • 48
1

I would never rely on object properties showing up in any particular, or even consistent, order when iterating with a "for ... in" loop. It's just a fragile way to put a program together, especially when it's so easy to explicitly impose your own order.

When iterating through arrays, you should not be using "for ... in" loops anyway so the point is moot; obviously if you iterate properly with a numeric index, you'll traverse the properties in a consistent repeatable order.

If you serialize an array into JSON representation, there must be something for every indexed property from position 0 up to the array length. That means that a sparse array of length 1000000 is problematic size-wise but workable.

Pointy
  • 371,531
  • 55
  • 528
  • 584
0

Enumerations over arrays are ordered in terms of index. If you enumerate (for in) or for loop over an array it will be ordered.

So if you create two arrays with the items in different orders then they are not identical.

Enumerations over objects are ordered based on whatever the browser feels like.

I believe some go alphabetically, some put numbers at the start, some at the end.

Raynos
  • 156,883
  • 55
  • 337
  • 385