オブジェクトのキーの順序

上記リンク先の手法は、新たなオブジェクトにキーを配列に入れてソートした後、その順にプロパティ値として入れる方法だ。が、この方法では完全にソートすることはできない。

仕様的にも実装的にも無理である。

仕様的に

  • ECMAScript 5th 仕様には、プロパティ列挙の順序は書かれていない
  • ECMAScript 6th Draft には、9.1.11 [[Enumerate]] ()The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below. と明記されている。

要するに実装まかせであり、仕様として順序は保証していない。

実装的に

上記のように仕様はないとはいえ、皆似たような順序になるよう調整されている。

概ね、strawman:enumeration [ES Wiki]の下部に載っているような順序になる。

  1. Uint32範囲内の整数になるキー値なら、Index値として順にソートされ、先にならぶ
  2. その他は定義された順

v8(Chrome), Chakra(IE11), JSC(Safari) はそんな感じ。ただし、微妙にずれがある。

v8 は 0 - 0xFFFFFFFF(2^32-1) で、Chakra, JSCは 0 - 0xFFFFFFFF-1(2^32-2) がIndex値として捉えられる範囲っぽい。

SpiderMonkey(Firefox)の謎挙動

上記では挙げなかったSpiderMonkeyであるが…。

999と1000が境界っぽく、意味不明である。(Firefox25調べ)

var obj = { "a":"", 1:"", 100:"", 999:"", 3:"" }; for (var key in obj){ console.log(key); }
// 1
// 3
// 100
// 999
// a

だが、1000 以上になると、Index値としての対象にならない模様。

var obj = { "a":"", 1:"", 100:"", 1000:"", 3:"" }; for (var key in obj){ console.log(key); }
// 1
// 3
// 100
// a
// 1000

話が脱線したが、ともかく、整数に変換可能なキーは勝手にソートされるため、オブジェクトに入れ直す手法は完全ではない。