vxl
vxl

Reputation: 103

jQuery parseJson object direction (IE and Firefox vs Opera and Chrome)

AJAX request returns JSON string like: {"1015": {some data here}, "1001": {some data here} - it is JSON encoded PHP array.

jQuery.parseJSON function return Javascript object and look where the problem is: IE8 and FF4 return object with the same element order: 1015, 1001 (what I think is a right way), but Opera11 and Chrome14 return object with opposite order: 1001, 1015 (but proceeded JSON string is the same).

Is there any workaround for this problem?

Upvotes: 1

Views: 1617

Answers (1)

Dmitry Traytel
Dmitry Traytel

Reputation: 111

This isn't a browser problem as much as it is a misuse of data structures.

An array is an ordered set of objects. A javascript collection/object is, by definition, an unordered set. The ECMA Standard backs this up.

There is a relatively ancient issue on the chromium V8 project that has a lengthy discussion on the subject: http://code.google.com/p/v8/issues/detail?id=164

The gist of it is that Chrome and Opera (and IE9 in fact) are sorting the numerically keyed members of your object and placing them before any members with string keys. This is done for efficiency reasons when accessing the object and it is working as intended in those browsers. FF and IE < 9 are preserving the order of a structure that should not be ordered, and while they're doing nothing wrong, that behavior is less right than that of Chrome, Opera, and IE9.

You basically have three ways to resolve this in your project:

  1. Call array_values() on your data to make it non-associative. When you json_encode it, it will be encoded as an array by default. The order will then be whatever order it was defined as in PHP. Since you don't want to lose your keys, you should store them in the object data. This is the preferred solution and least likely to break long-term.

  2. Define the order you want your data to be in and pass that as an array along with your object data. Not as great as the above, since you end up passin gmore data than you really need and it shifts the burden to the client.

  3. Convert your keys to strings with some alpha character at the beginning or end of each key. This is only a good option if you're working with a legacy project and barely have any control of your architecture.

The fact is that you, as a developer, have no guarantee that an unordered object's order will be preserved. As web standards move into that direction, and ECMA standards and drafts of future standard continue to make the rules, other browsers will shift to this behavior. Might as well adjust now.

Moral of the story: If you need to preserve order, use an array.

Upvotes: 5

Related Questions