使用Proxy创建动态不可配置属性

时间:2016-12-01 22:52:55

标签: javascript ecmascript-6 es6-proxy

我想使用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说:

  

如果属性不作为目标对象的自有属性存在,或者它作为目标对象的可配置自己的属性存在,则不能将该属性报告为不可配置。

但它没有解释这背后的原因是什么。

此错误是否有解决方法?

2 个答案:

答案 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'));

副作用(显然)是创建的属性,无法删除(因为它是不可配置的),这意味着例如我以后不能将其报告为不存在,但在我的情况下它并不重要