ts访问器装饰器的疑问?

我刚刚学习访问器的装饰器,现在我想对set访问器进行装饰,期待返回:set装饰器 + name,但是一直没有效果,请教一下懂的同学。
demo:


// 访问器装饰器
function testDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
    descriptor.set = (name: string) =>{ // set如何访问 this._name
        name = "set装饰器:" + name;
        return name;
    }
}

// 类
class Test {
    private _name: string;
    constructor(name: string) {
        this._name = name;
    }
    get name() {
        return this._name;
    }
    @testDecorator // 希望通过装饰器,对this._name做一点处理
    set name(name: string) {
        this._name = name;
    }
}
const test = new Test('111');
test.name = '222'
console.log(test.name); // 还是输出:  111, 期待输出:  set装饰器:222
阅读 1.4k
2 个回答

你需要稍微修改装饰器的实现。你可以把原始的set方法保存在一个变量中,然后在装饰器的set方法中调用它。这里是修复后的代码:

// 访问器装饰器
function testDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
    const originalSet = descriptor.set; // 保存原始的 set 方法

    descriptor.set = function(name: string) {
        name = "set装饰器:" + name;
        originalSet.call(this, name); // 使用 .call(this, ...) 调用原始的 set 方法
    }
}

// 类
class Test {
    private _name: string;
    constructor(name: string) {
        this._name = name;
    }
    get name() {
        return this._name;
    }
    @testDecorator // 希望通过装饰器,对this._name做一点处理
    set name(name: string) {
        this._name = name;
    }
}
const test = new Test('111');
test.name = '222'
console.log(test.name); // 输出: set装饰器:222

现在,装饰器将正确地修改name值并将其保存在_name属性中。

若要启用实验性的装饰器特性,你必须在命令行或tsconfig.json里启用experimentalDecorators编译器选项,

你启用了吗?

logo
Microsoft
子站问答
访问
宣传栏