为什么 Object.keys() 和 Object.getOwnPropertyNames() 在使用 ownKeys 处理程序调用 Proxy 对象时会产生不同的输出?
Why does Object.keys() and Object.getOwnPropertyNames() produce different output when called on a Proxy object with ownKeys handler?
我有以下代理:
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
});
MDN 表示:
This trap can intercept these operations:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
因此,我希望 Object.getOwnPropertyNames()
和 Object.keys()
产生相同的输出。但是,Object.getOwnPropertyNames(p)
returns ['a', 'b']
(如预期),但 Object.keys(p)
returns 是一个空数组。这是为什么?
此外,如果我向该对象添加一个 属性 而不是由 ownKeys
处理程序返回(例如 c
),它会被两个函数忽略(它们不'改变他们的输出)。但是,当我添加由 ownKeys
处理程序(例如 a
)返回的 属性 时,现在 Object.keys(p)
returns ['a']
.
代码片段:
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
});
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // []
p.c = true;
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // []
p.a = true;
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // ['a']
Object.keys
和Object.getOwnPropertyNames
的区别在于后者returns拥有属性,不管它们是否可枚举。
Proxy
添加到对象的属性是不可枚举的,不会出现在Object.keys
中,但会出现在Object.getOwnPropertyNames
中
通常,通过赋值或属性初始化器添加的属性默认是可枚举的,而通过Object.assign
、new Proxy
等方法添加的属性默认是不可枚举的.
在 MDN 上有更多关于 属性 所有权和可枚举性的内容,您还可以在其中找到这个 table,它概述了两种方法的区别
对象上Object.keys()
and Object.getOwnPropertyNames()
is that Object.keys()
will invoke [[GetOwnProperty]]
的区别,如果returned 属性描述符为,则只将属性添加到结果列表可枚举。由于对象没有这样的 属性,[[GetOwnProperty]]
将 return undefined
并且忽略 属性(名称)。
您可以通过实施 getOwnPropertyDescriptor
:
在代理中 overwrite/implement [[GetOwnProperty]]
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
getOwnPropertyDescriptor(k) {
return {
enumerable: true,
configurable: true,
};
}
});
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // ['a', 'b']
我有以下代理:
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
});
MDN 表示:
This trap can intercept these operations:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
因此,我希望 Object.getOwnPropertyNames()
和 Object.keys()
产生相同的输出。但是,Object.getOwnPropertyNames(p)
returns ['a', 'b']
(如预期),但 Object.keys(p)
returns 是一个空数组。这是为什么?
此外,如果我向该对象添加一个 属性 而不是由 ownKeys
处理程序返回(例如 c
),它会被两个函数忽略(它们不'改变他们的输出)。但是,当我添加由 ownKeys
处理程序(例如 a
)返回的 属性 时,现在 Object.keys(p)
returns ['a']
.
代码片段:
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
});
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // []
p.c = true;
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // []
p.a = true;
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // ['a']
Object.keys
和Object.getOwnPropertyNames
的区别在于后者returns拥有属性,不管它们是否可枚举。
Proxy
添加到对象的属性是不可枚举的,不会出现在Object.keys
中,但会出现在Object.getOwnPropertyNames
通常,通过赋值或属性初始化器添加的属性默认是可枚举的,而通过Object.assign
、new Proxy
等方法添加的属性默认是不可枚举的.
在 MDN 上有更多关于 属性 所有权和可枚举性的内容,您还可以在其中找到这个 table,它概述了两种方法的区别
对象上Object.keys()
and Object.getOwnPropertyNames()
is that Object.keys()
will invoke [[GetOwnProperty]]
的区别,如果returned 属性描述符为,则只将属性添加到结果列表可枚举。由于对象没有这样的 属性,[[GetOwnProperty]]
将 return undefined
并且忽略 属性(名称)。
您可以通过实施 getOwnPropertyDescriptor
:
[[GetOwnProperty]]
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
getOwnPropertyDescriptor(k) {
return {
enumerable: true,
configurable: true,
};
}
});
console.log(Object.getOwnPropertyNames(p)); // ['a', 'b']
console.log(Object.keys(p)); // ['a', 'b']