Rem*_*sen 8 javascript decorator typescript ecmascript-7
我读过"如何实现打字稿装饰器?" 和多个来源,但我有一些东西,也没有能够与装饰.
class FooBar {
public foo(arg): void {
console.log(this);
this.bar(arg);
}
private bar(arg) : void {
console.log(this, "bar", arg);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们调用函数foo:
var foobar = new FooBar();
foobar.foo("test");
Run Code Online (Sandbox Code Playgroud)
该对象FooBar由console.log(this);in 登录到控制台中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;
}
};
}
Run Code Online (Sandbox Code Playgroud)
我们使用相同的功能,但装饰:
class FooBar {
@log
public foo(arg): void {
console.log(this);
this.bar(arg);
}
@log
private bar(arg) : void {
console.log(this, "bar", arg);
}
}
Run Code Online (Sandbox Code Playgroud)
foo我们像以前一样调用:
var foobarFoo = new FooBar();
foobarFooBar.foo("test");
Run Code Online (Sandbox Code Playgroud)
该对象Window由console.log(this);in 登录到控制台中foo
并且bar永远不会foo因为this.bar(arg);原因而被调用Uncaught TypeError: this.bar is not a function.
问题是装饰者this内部的硬编码log:
value.value.apply(this, args);
Run Code Online (Sandbox Code Playgroud)
我怎样才能保存原始this价值?
Dav*_*ret 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;
}
};
}
Run Code Online (Sandbox Code Playgroud)
这样它将使用函数的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;
}
Run Code Online (Sandbox Code Playgroud)
此答案中的更多详细信息 - 请参阅"示例 - 没有参数>注释"下的"Bad vs Good"示例
| 归档时间: |
|
| 查看次数: |
2320 次 |
| 最近记录: |