Javascript 为什么在使用ownKeys处理程序调用代理对象时,Object.keys()和Object.getOwnPropertyNames()会产生不同的输出?
我有以下代理人:Javascript 为什么在使用ownKeys处理程序调用代理对象时,Object.keys()和Object.getOwnPropertyNames()会产生不同的输出?,javascript,ecmascript-6,es6-proxy,Javascript,Ecmascript 6,Es6 Proxy,我有以下代理人: const p = new Proxy({}, { ownKeys(target) { return ['a', 'b']; }, }); 他说: 此陷阱可以拦截以下操作: Object.getOwnPropertyNames() Object.getOwnPropertySymbols() Object.keys() Reflect.ownKeys() 因此,我期望Object.getOwnPropertyNames()和Object.keys()产生相
const p = new Proxy({}, {
ownKeys(target) {
return ['a', 'b'];
},
});
他说:
此陷阱可以拦截以下操作:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
Object.getOwnPropertyNames()
和Object.keys()
产生相同的输出。但是,Object.getOwnPropertyNames(p)
返回['a',b']
(如预期的那样),但是Object.keys(p)
返回一个空数组。为什么呢
此外,如果我向该对象添加了一个属性,而该属性不是由ownKeys
处理程序返回的(例如c
),则两个函数都会忽略它(它们不会更改输出)。但是,当我添加由ownKeys
处理程序返回的属性(例如a
)时,Object.keys(p)
现在返回['a']
代码段:
const p=new Proxy({}{
ownKeys(目标){
返回['a','b'];
},
});
console.log(Object.getOwnPropertyNames(p));//['a','b']
console.log(Object.keys(p));//[]
p、 c=正确;
console.log(Object.getOwnPropertyNames(p));//['a','b']
console.log(Object.keys(p));//[]
p、 a=真;
console.log(Object.getOwnPropertyNames(p));//['a','b']
console.log(Object.keys(p));//['a']
Object.keys和Object.getOwnPropertyNames
之间的区别在于后者返回自己的属性,而不管它们是否可枚举
通过代理添加到对象中的属性是不可枚举的,不会显示在对象.key
中,但会显示在对象.getOwnPropertyNames
通常,默认情况下,通过赋值或属性初始值设定项添加的属性是可枚举的,而通过Object.assign
、new Proxy
等方法添加的属性是不可枚举的
这里有更多关于属性所有权和可枚举性的内容,您也可以在这张表中找到这两种方法的区别
和之间的区别在于对象上的区别,并且仅当返回的属性描述符可枚举时才将属性添加到结果列表中。由于对象没有这样的属性,[[GetOwnProperty]]
将返回未定义的
,并且忽略该属性(名称)
通过实现getOwnPropertyDescriptor
,可以覆盖/实现代理中的[[GetOwnProperty]]
:
const p=new Proxy({}{
ownKeys(目标){
返回['a','b'];
},
getOwnPropertyDescriptor(k){
返回{
可枚举:正确,
对,,
};
}
});
console.log(Object.getOwnPropertyNames(p));//['a','b']
console.log(Object.keys(p));//['a','b']
Atjavascript
At Answer值仅由处理程序返回,而不是在target
对象上设置,是吗?在target
对象{}
上似乎没有设置实际属性;虽然{}
在Proxy()
调用之外没有标识符,但可以使用函数的参数引用目标对象。数组或对象仅由函数返回
,而不是设置在目标
{}
?@FelixKling因此,按照您的思路,如果使用对象定义了a和b,则应该能够列出它们。defneProperty
并将其设置为可枚举,对吗?我试过了,但没有成功。知道为什么吗?我不知道那张桌子,太棒了!