将装饰器与 class 构造函数一起使用
Using decorators together with class constructors
我正在尝试在 class 中使用装饰器,该装饰器使用参数进行初始化,但是当装饰器应用于我的函数时,构造函数中设置的值未定义。请看下面的玩具示例:
function someDecorator() {
return (target: any, _2: any, descriptor: PropertyDescriptor) => {
const func = descriptor.value.bind(target);
descriptor.value = () => {
console.log('Doing decorator stuff!');
func();
}
}
}
class Foo {
public constructor(private thing: string) { }
@someDecorator()
bar() {
console.log(this.thing);
}
}
new Foo('Hello world!').bar();
我当然想要输出:
> Doing decorator stuff!
> Hello world!
但遗憾的是我得到了输出:
> Doing decorator stuff!
> undefined
有人能给我指出正确的方向吗?
你得到的target
将是class的原型,而不是任何实例。因此,将方法绑定到 target
将具有丢失实际实例的 this
上下文的效果,而是在原型的上下文中调用它,原型通常不会有任何这些实例属性。
您必须等到 class 方法实际被调用才能获得合适的 this
。因此,忘记 target
,而是在新方法中将 func
绑定到 this
。并注意箭头函数不会有自己的 this
所以 descriptor.value
不应该是箭头函数(没有更多的跳箍)。所以我建议改用传统的匿名 function
。因此,将 someDecorator()
的实现更改为如下所示:
function someDecorator() {
return (target: any, _2: any, descriptor: PropertyDescriptor) => {
const func = descriptor.value; // don't bind here
descriptor.value = function (...args: any) {
console.log('Doing decorator stuff!');
func.apply(this, args); // bind here (applying args is optional I guess)
}
}
}
现在应该可以了:
new Foo('Hello world!').bar();
// Doing decorator stuff!
// Hello world!
希望对您有所帮助。祝你好运!
我正在尝试在 class 中使用装饰器,该装饰器使用参数进行初始化,但是当装饰器应用于我的函数时,构造函数中设置的值未定义。请看下面的玩具示例:
function someDecorator() {
return (target: any, _2: any, descriptor: PropertyDescriptor) => {
const func = descriptor.value.bind(target);
descriptor.value = () => {
console.log('Doing decorator stuff!');
func();
}
}
}
class Foo {
public constructor(private thing: string) { }
@someDecorator()
bar() {
console.log(this.thing);
}
}
new Foo('Hello world!').bar();
我当然想要输出:
> Doing decorator stuff!
> Hello world!
但遗憾的是我得到了输出:
> Doing decorator stuff!
> undefined
有人能给我指出正确的方向吗?
你得到的target
将是class的原型,而不是任何实例。因此,将方法绑定到 target
将具有丢失实际实例的 this
上下文的效果,而是在原型的上下文中调用它,原型通常不会有任何这些实例属性。
您必须等到 class 方法实际被调用才能获得合适的 this
。因此,忘记 target
,而是在新方法中将 func
绑定到 this
。并注意箭头函数不会有自己的 this
所以 descriptor.value
不应该是箭头函数(没有更多的跳箍)。所以我建议改用传统的匿名 function
。因此,将 someDecorator()
的实现更改为如下所示:
function someDecorator() {
return (target: any, _2: any, descriptor: PropertyDescriptor) => {
const func = descriptor.value; // don't bind here
descriptor.value = function (...args: any) {
console.log('Doing decorator stuff!');
func.apply(this, args); // bind here (applying args is optional I guess)
}
}
}
现在应该可以了:
new Foo('Hello world!').bar();
// Doing decorator stuff!
// Hello world!
希望对您有所帮助。祝你好运!