我已经阅读了"How to implement a typescript decorator?"和多个来源,但我有一些东西,也没有能够用装饰器。
class FooBar {
public foo(arg): void {
console.log(this);
this.bar(arg);
}
private bar(arg) : void {
console.log(this, "bar", arg);
}
}
如果我们调用函数foo
:
var foobar = new FooBar();
foobar.foo("test");
FooBar
console.log(this);
在控制台中记录了对象foo
"FooBar {foo: function, bar: function} bar test"
中console.log(this, "bar", arg);
在控制台中记录了字符串bar
。
现在让我们使用装饰器:
function log(target: Function, key: string, value: any) {
return {
value: (...args: any[]) => {
var a = args.map(a => JSON.stringify(a)).join();
var result = value.value.apply(this, args); // How to avoid hard coded this?
var r = JSON.stringify(result);
console.log(`Call: ${key}(${a}) => ${r}`);
return result;
}
};
}
我们使用相同的功能但装饰:
class FooBar {
@log
public foo(arg): void {
console.log(this);
this.bar(arg);
}
@log
private bar(arg) : void {
console.log(this, "bar", arg);
}
}
我们像之前一样调用foo
:
var foobarFoo = new FooBar();
foobarFooBar.foo("test");
Window
console.log(this);
在控制台中记录了对象foo
bar
永远不会调用foo
,因为this.bar(arg);
会导致Uncaught TypeError: this.bar is not a function
。
问题是this
装饰器中的硬编码log
:
value.value.apply(this, args);
如何保存原始this
值?
答案 0 :(得分:17)
不要使用箭头功能。使用函数表达式:
function log(target: Object, key: string, value: any) {
return {
value: function(...args: any[]) {
var a = args.map(a => JSON.stringify(a)).join();
var result = value.value.apply(this, args);
var r = JSON.stringify(result);
console.log(`Call: ${key}(${a}) => ${r}`);
return result;
}
};
}
这样,当调用日志时,它将使用函数的this
上下文而不是this
的值。
顺便说一句,我建议编辑descriptor / value参数并返回,而不是通过返回一个新的描述符来覆盖它。这样你就可以将属性保存在描述符中,并且不会覆盖另一个装饰器可能对描述符做的事情:
function log(target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
var originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
var a = args.map(a => JSON.stringify(a)).join();
var result = originalMethod.apply(this, args);
var r = JSON.stringify(result);
console.log(`Call: ${key}(${a}) => ${r}`);
return result;
};
return descriptor;
}
More details in this answer - 请参阅“示例 - 没有参数&gt;注释”下的“Bad vs Good”示例
答案 1 :(得分:0)
我相信你可以使用
var self = this;
为了在特定点保留'this'。然后,只需在稍后您需要特定self
this