Reflect.ownKeys(obj)和Object.keys(obj)有什么区别?

时间:2015-12-24 07:36:19

标签: javascript ecmascript-6 es2015

在一个真实的简单案例中测试它们会产生相同的输出:

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)不同?

4 个答案:

答案 0 :(得分:36)

Object.keys()会返回@Override public void onBackPressed() { if (isFullscreen.equals(true)){ isFullscreen = false; you.setFullscreen(false); }else { super.onBackPressed(); } } 个字符串,这些字符串是对象自己的可枚举属性。

Reflect.ownKeys(obj)返回相当于:

array

Object.getOwnPropertyNames(target). concat(Object.getOwnPropertySymbols(target)) 方法返回直接在给定对象上找到的所有属性(enumerable 或不)的数组。

Object.getOwnPropertyNames()方法返回直接在给定对象上找到的所有symbol属性的数组。

Object.getOwnPropertySymbols()

要展示的小fiddle

答案 1 :(得分:12)

首先,一个例子(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可以枚举的属性,但通过原型链继承的属性除外。有关详细信息,请参阅the MDN description

<强>要点:

Reflect.ownKeys()相当于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)),它将返回可枚举和不可枚举的属性

,而

Object.keys()返回可枚举属性,但不返回非可枚举属性(这是Object.getOwnPropertyNames()的特征)。

答案 2 :(得分:5)

  • Object.keys仅返回可枚举的字符串键; Reflect.ownKeys返回字符串和符号键,无论它们的可枚举性如何。两者都只在自己的财产上运作。
  • 如果参数不是对象而不是Object.keysnull(例如undefined),则
  • Object.keys(1)返回一个空数组,而Reflect.ownKeys会抛出{ {1}}。
  • TypeError是在ES6中引入的,旧版JavaScript引擎不支持。

答案 3 :(得分:0)

除了已经提到的其他答案外,规范还保证Reflect.ownKeys 按以下顺序返回键(和符号):

  • 整数数字键,按升序(0,1,2)
  • 字符串键,按插入对象的顺序
  • 符号键

[[OwnPropertyKeys]]调用的内部Reflect.ownKeys方法要求此顺序。

相反,Object.keys调用EnumerableOwnPropertyNames,要求:

  
      
  1. properties的元素进行排序,以使它们与Iterator产生的相对顺序相同,如果使用O调用EnumerateObjectProperties内部方法,则返回的迭代器相同。
  2.   

EnumerateObjectProperties显式地未指定返回属性的任何顺序的地方:

  

未指定枚举属性的机制和顺序

因此,如果要绝对确定,则在遍历对象属性的同时,按插入顺序对非数字键进行迭代,请确保使用Reflect.ownKeys(或{ {3}},它也会调用[[OwnPropertyKeys]])。

(所有这些都说明了,尽管Object.keys,其变体,for..in循环和JSON.stringify都以未指定的,依赖于实现的顺序进行正式迭代,但环境通常以相同的可预测方式进行迭代幸运的是,以Reflect.ownKeys的顺序订购)