我正在尝试实现一个覆盖属性 (1) 并定义隐藏属性 (2) 的装饰器。假设以下示例:
function f() {
return (target: any, key: string) => {
let pKey = '_' + key;
// 1. Define hidden property
Object.defineProperty(target, pKey, {
value: 0,
enumerable: false,
configurable: true,
writable: true
});
// 2. Override property get/set
return Object.defineProperty(target, key, {
enumerable: true,
configurable: true,
get: () => target[pKey],
set: (val) => {
target[pKey] = target[pKey] + 1;
}
});
};
}
class A {
@f()
propA = null;
propB = null;
}
let a = new A();
console.log(Object.keys(a), a.propA, a._propA, a);
哪个输出:
[ 'propB' ] 1 1 A { propB: null }
但是,我宁愿期望:
[ 'propA', 'propB' ] 1 1 A { propA: 1, propB: null }
因为enumerable
是true
为了propA
。
现在,如果get
我set
用
get: function () {
return this[pKey]
},
set: function (val) {
this[pKey] = this[pKey] + 1;
}
现在的输出是:
[ '_propA', 'propB' ] 1 1 A { _propA: 1, propB: null }
虽然enumerable
被明确设置为false
for _propA
in f
。
因此,尽管这些行为可能很奇怪,但我想了解这里发生了什么,以及我将如何实现我想要得到的东西?