如何使用Decorator将类字段转为Getter/Setter并保留初始值?
如何用装饰器实现保留初始值的Getter/Setter?
你这个问题很典型——咱们先拆解下初始值丢失的原因:你当前的装饰器里声明了一个全新的val变量,但它完全没和原来bar = 0的初始值挂钩。类字段的初始值其实是通过descriptor.initializer这个函数传递的,你的装饰器没用到它,自然就把初始值丢了。
下面是修正后的装饰器实现,既能完美保留初始值,又能实现自定义的setter行为:
function accessor(target, name, descriptor) { // 调用initializer获取类字段的初始值(这里就是你设置的0) let val = descriptor.initializer?.(); return { // 自定义setter逻辑 set: function(newVal) { val = newVal; console.log("setter called with value:", newVal); }, // 对应的getter get: function() { return val; }, // 继承原字段的枚举、可配置特性,避免意外问题 enumerable: descriptor.enumerable, configurable: descriptor.configurable }; }
测试一下这个版本:
class Foo { @accessor bar = 0; } const foo = new Foo(); console.log(foo.bar); // 输出:0,初始值保住了! foo.bar = 1; // 输出:setter called with value: 1 console.log(foo.bar); // 输出:1
补充说明
descriptor.initializer是类字段装饰器里专门用来获取初始值的函数,调用它就能拿到你写在字段后面的初始值。如果你的环境不支持可选链(?.),可以换成descriptor.initializer ? descriptor.initializer() : undefined。- 一定要把原descriptor的
enumerable和configurable属性复制过来,不然你的getter/setter可能会在遍历对象、修改属性时出现不符合预期的行为。
内容的提问来源于stack exchange,提问作者Silver
相关产品推荐
相关产品推荐

