実際の単純なケースでそれらをテストすると、同じ出力が得られます。
_const obj = {a: 5, b: 5};
console.log(Reflect.ownKeys(obj));
console.log(Object.keys(obj));
// Result
['a', 'b']
['a', 'b']
_
Reflect.ownKeys(obj)
がObject.keys(obj)
と異なる出力を生成するのはいつですか?
Object.keys()
は、オブジェクト自身のenumerableプロパティである文字列のarray
を返します。
Reflect.ownKeys(obj)
は以下と同等のものを返します:
_Object.getOwnPropertyNames(target).
concat(Object.getOwnPropertySymbols(target))
_
Object.getOwnPropertyNames()
メソッドは、すべてのプロパティの配列を返します( enumerable
or not)指定されたオブジェクトに直接見つかります。
Object.getOwnPropertySymbols()
メソッドは、指定されたオブジェクトで直接検出されるすべての symbol
プロパティの配列を返します。
_var testObject;
Object.defineProperty(testObject, 'myMethod', {
value: function () {
alert("Non enumerable property");
},
enumerable: false
});
//does not print myMethod since it is defined to be non-enumerable
console.log(Object.keys(testObject));
//prints myMethod irrespective of it being enumerable or not.
console.log(Reflect.ownKeys(testObject));
_
小さな fiddle
を示します。
まず、例( ES6Fiddle ):
_// getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 1;
console.log(Object.keys(my_obj)); // console ['foo']
console.log(Reflect.ownKeys(my_obj)); // console ['getFoo', 'foo']
_
ここで、Reflect.ownKeys()
は、ターゲットオブジェクト自体のプロパティキーの配列を返します。つまり、指定されたオブジェクトで直接検出されたすべてのプロパティの配列(列挙可能かどうかにかかわらず)を、指定されたオブジェクトで直接検出されたすべての symbol プロパティの配列と連結します。
Object.ownKeys()
は、列挙可能なプロパティのみを返します。
列挙可能なプロパティは、プロトタイプチェーンを通じて継承されたプロパティを除いて、 for ... in loop で列挙できるプロパティです。詳細は MDNの説明 を参照してください。
まとめ:
Reflect.ownKeys() は、列挙可能なプロパティと列挙できないプロパティの両方を返すObject.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
と同等です
一方
Object.keys() は列挙可能なプロパティを返しますが、列挙不可能なプロパティは返しません(これは Object.getOwnPropertyNames() の特性です)。
他の回答がすでに述べたことに加えて、Reflect.ownKeys
はまた、次の順序でキー(および記号)を返す仕様によって保証されています。
この順序は、 [[OwnPropertyKeys]]
によって呼び出される内部の Reflect.ownKeys
メソッドで必要です。
対照的に、Object.keys
は EnumerableOwnPropertyNames
を呼び出します。
properties
の要素を順序付けして、 EnumerateObjectProperties 内部メソッドがOで呼び出された場合に返されるイテレーターによって生成されるのと同じ相対順序になるようにします。
ここで EnumerateObjectProperties を明示的に指定しないプロパティが返される順序:
プロパティを列挙するメカニズムと順序は指定されていません
したがって、絶対に確実にしたい場合、オブジェクトのプロパティを反復処理するときに、非数値キーの挿入順序で反復処理する場合は、必ずReflect.ownKeys
(または Object.getOwnPropertyNames
は、[[OwnPropertyKeys]]
も呼び出します)。
(そうは言っても、Object.keys
、そのバリアント、for..in
ループ、およびJSON.stringify
はすべて、指定されていない、実装に依存する順序で公式に反復されますが、環境は通常、Reflect.ownKeys
と同じ予測可能な順序で反復します)