我想使用Proxy创建动态不可配置属性。我试过这个:
const proxy = new Proxy({}, {
getOwnPropertyDescriptor() {
return {
configurable: false,
enumerable: false,
};
},
});
console.log(Reflect.getOwnPropertyDescriptor(proxy, 'test'));
但是我收到了一个错误:
TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property 'test' which is either non-existant or configurable in the proxy target
MDN说:
如果属性不作为目标对象的自有属性存在,或者它作为目标对象的可配置自己的属性存在,则不能将该属性报告为不可配置。
但它没有解释这背后的原因是什么。
此错误是否有解决方法?
答案 0 :(得分:8)
不是真的。这是由于理想的不变量,如果你在一个对象中观察到一个不可配置的属性,它就不会神奇地消失。如果它也是不可写的,它的价值不能改变。
如果你不能依赖这个,getOwnPropertyDescriptor
基本没用。
强制您不使用不可配置的属性,或在目标中定义它们,这意味着您不会违反此不变量,因为不变量通过构造保留在目标上。也就是说,ECMAScript不允许您以破坏这些不变量的方式使用代理自定义。
6.1.7.3中定义的一些内部方法不变量是 基本完整性不变量。这些不变量是明确的 由代理对象强制执行的内部方法 部分。 ECMAScript实现必须在存在时是健壮的 所有可能的不变违规行为。
因此要么将属性报告为可配置,要么在目标中定义不可配置的属性。
如果你想要动态属性,我建议说谎属性是可配置的。然后添加一个返回defineProperty
的{{1}}陷阱,有效防止重新定义。
答案 1 :(得分:0)
似乎如果在getOwnPropertyDescriptor
陷阱内我在返回描述符之前在目标对象上定义了该属性,它就可以正常工作。
const proxy = new Proxy({}, {
getOwnPropertyDescriptor(target, property) {
const descriptor = {
configurable: false,
enumerable: false,
};
Reflect.defineProperty(target, property, descriptor);
return descriptor;
},
});
console.log(Reflect.getOwnPropertyDescriptor(proxy, 'test'));
副作用(显然)是创建的属性,无法删除(因为它是不可配置的),这意味着例如我以后不能将其报告为不存在,但在我的情况下它并不重要