Ordering

# liorean (17 years ago)

2008/5/31 Douglas Crockford <douglas at crockford.com>:

This program...

<html> <body><script> (function () { var keys = [ 'koda', 0, 'bosanda', 1, 'bosoya', 2 ];

var object = {}, table, i, name;

for (i = 0; i < keys.length; i += 1) {
    object[keys[i]] = i;
}

i = 0;
table = '<table><tbody><tr><th>' +
    'Insertion Order</th><th><code>for in</code> Order</th></tr>';
for (name in object) {
    table += '<tr><td>' + keys[i] + '</td><td>' + name + '</td></tr>';
    i += 1;
}
table += '</tbody></table>';
document.write(table);

})(); </script> </body></html>

...produces this result on current editions of Internet Explorer, Firefox, and Safari:

Insertion Order for in Order koda koda 0 0 bosanda bosanda 1 1 bosoya bosoya 2 2

It produces this result for Opera:

Insertion Order for in Order koda 0 0 1 bosanda 2 1 koda bosoya bosanda 2 bosoya

Opera appears to be optimizing array-like sequences.

Opera stores property names that are array indexes in a more space efficient manner than other property names, at the cost of not preserving insertion order when enumerating the properties.

What should ES3.1 say about member ordering? Should it remain unordered, or should Opera be required to conform, or should the other three be forced to adopt Opera's optimization?

ES4 requires enumeration order to follow insertion order, so the space optimisation Opera does break the ES4 rules. Opera have bugs about property access being a performance problem, and in the process of fixing that may change to another storage system, so aligning with Opera's current behaviour would be a bad idea.

I think ES3.x should either follow ES4 or stay silent on the issue, especially considering Opera is the only browser that doesn't use insertion order enumeration.