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

问题描述 投票:0回答:4

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

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

javascript ecmascript-6
4个回答
69
投票

Object.keys()
返回
array
字符串,它们是对象自己的 enumerable 属性。

Reflect.ownKeys(obj)
返回以下内容的等价*:

Object.getOwnPropertyNames(target).
                   concat(Object.getOwnPropertySymbols(target))

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

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));

(*) “

Reflect.ownKeys(target)
通常等同于
Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
但是,如果对象具有自定义
[[OwnPropertyKeys]]
方法(例如通过代理的 ownKeys 处理程序),键的顺序可能会不同。” 来源:MDN


15
投票

首先,一个例子(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.keys()
只会返回可枚举的属性。

可枚举属性是那些可以通过 for...in 循环 枚举的属性,但通过原型链继承的属性除外。请参阅MDN 描述了解更多详细信息。

总结:

Reflect.ownKeys()相当于

Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
,它将返回可枚举和不可枚举属性

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


7
投票

除了其他答案已经提到的内容之外,规范还

保证
按以下顺序返回键(和符号):

整数数字键,按升序排列(0,1,2)
  • 字符串键,
  • 按照它们插入对象的顺序
  • 符号键
  • 此顺序是内部

Reflect.ownKeys

 方法所必需的,该方法由 
[[OwnPropertyKeys]]
 调用。
相反,

Reflect.ownKeys

调用

Object.keys
,这需要:

    EnumerableOwnPropertyNames
  1. 的元素进行排序,以便它们的相对顺序与使用 O 调用
    EnumerateObjectProperties
    内部方法时返回的迭代器生成的相对顺序相同。
其中
EnumerateObjectProperties

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

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

因此,如果您想
绝对确定

,在迭代对象属性时,您按照非数字键的插入顺序进行迭代,请确保使用properties(或

Reflect.ownKeys
,它也会调用
Object.getOwnPropertyNames
)。

(尽管如此,虽然

[[OwnPropertyKeys]]

、其变体、

Object.keys
循环和
for..in
都以未指定的、依赖于实现的顺序进行正式迭代,但幸运的是,环境通常以与
JSON.stringify
相同的可预测顺序进行迭代) )
    


6
投票
    Reflect.ownKeys
  • 仅返回可枚举字符串键;
    Object.keys
    返回字符串和符号键,无论它们的可枚举性如何。两者均仅在自己的财产上运营。
    如果参数不是对象且不是 
    Reflect.ownKeys
  • Object.keys
    (例如 
    null
    ),
    undefined
    将返回一个空数组,而
    Object.keys(1)
    会抛出
    Reflect.ownKeys
  • TypeError
  • 是随 ES6 引入的,旧版 JavaScript 引擎不支持。
    
        
© www.soinside.com 2019 - 2024. All rights reserved.