Javascript 如何避免硬编码?装修工
我已经阅读了很多资料,但是有一些我对装饰师也没能做到的事情Javascript 如何避免硬编码?装修工,javascript,typescript,decorator,ecmascript-2016,Javascript,Typescript,Decorator,Ecmascript 2016,我已经阅读了很多资料,但是有一些我对装饰师也没能做到的事情 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(); foo
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(这个“bar”,arg)记录在控制台中代码>在栏中
现在让我们使用一个装饰器:
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;
}
};
}
value.value.apply(this, args);
我们使用相同的功能,但经过修饰:
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");
对象窗口
通过console.log(此)记录在控制台中代码>在foo
而bar
从不被foo
调用,因为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;
}
};
}
value.value.apply(this, args);
如何保存原始此值?我相信您可以使用
var self = this;
为了在该特定点保留“this”。然后,只需在稍后的点上使用self
,您可能希望该此不使用箭头功能。使用函数表达式:
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;
}
};
}
这样,当调用log时,它将使用函数的this
上下文,而不是this
的值
顺便说一下,我建议编辑描述符/值参数并返回它,而不是通过返回新的描述符来覆盖它。这样,您可以将属性当前保留在描述符中,并且不会覆盖其他装饰程序可能对描述符所做的操作:
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;
}
函数日志(目标:对象,键:字符串,描述符:TypedPropertyDescriptor-参见“示例-无参数>注释”下的“坏与好”示例)感谢您尝试回答,但当使用装饰器时,我无法控制特定的点。感谢您的回答,我没有注意到我使用的是箭头函数。@是的,很容易出错。我没有注意到,直到我在操场上弹出它,看到javascript在做这件事时,
OP的代码似乎来自my博客文章--我会更新它的!:)我也有这个问题,在一个很好的例子中,一篇博客文章更新了内容!一个挑剔:似乎目标
的类型应该是对象
而不是函数
,因为它是类的原型。