🎄
ENCA 8日目: プロパティ列挙順一律化
Reflect.ownKeys
のプロパティ列挙順
ES2015 Reflect.ownKeys
は対象オブジェクトが持つ [[OwnPropertyKeys]]
内部メソッドを呼び出します。Proxy
や Module Namespace オブジェクトのような Exotic Object にはそれぞれ定義された [[OwnPropertyKeys]]
内部メソッドで順番が定義されますが、普通のオブジェクトは OrdinaryOwnPropertyKeys
で定義された順に列挙されます。
OrdinaryOwnPropertyKeys
は以下の順で列挙します。
- 配列のインデックスとなりうる整数(文字列)プロパティ(array index)をその数の順番で列挙する
- 1 以外の文字列プロパティを作成順に列挙する
-
Symbol
プロパティを作成順に列挙する
const obj = {
[3]: 3,
foo: "foo",
[1]: 1,
[Symbol("bar")]: "bar",
"0": 0,
baz: "baz",
};
console.log(Reflect.ownKeys(obj)); // ["0", "1", "3", "foo", "baz", Symbol(bar)]
プロパティ列挙順一律化
ES2020 for-in
mechanics の提案により、今まで実装依存だった for...in の列挙順が定められました。
なお for...in はレガシー機能で、[[Prototype]]
のもつ列挙可能なプロパティも対象となってしまうため使わない方が良いです。ESLint の guard-for-in ルールにより、Object.hasOwn
によるプロパティ所有チェックをちゃんとしているか確かめることが可能ですが、通常 Object.keys
や Object.entries
を使ったほうが良いと思います。
さて for...in の列挙順が定められたことに呼応して、Object.keys
, Object.values
, Object.entries
, JSON.parse
そして JSON.stringify
の列挙順も Reflect.ownKeys
と一律同じにしようという話になり、承認されました。
Discussion