我正在将一个角度1的应用程序从javascript迁移到typescript。实际上一切都已完成,但我无法理解一个具体案例。
我有一些使用链接功能的指令。
伪代码中的:
class SomeDirective implements ng.IDirective{
static $inject=['someService'];
public restrict: string='EA';
public scope: any;
constructor(private someService: SomeService){
this.scope={
data: '='
}
}
}
现在我想定义一个像
这样的链接函数public link(scope, ele, attrs){
do some action with this.someService.someField
}
如果我在类中定义了这个方法,那么我会收到一个错误:未找到属性'someField'。
如果我在构造函数中按如下方式定义方法,那么它确实有效。有什么区别?
this.link=(scope,ele,attrs)=>{
do some action with this.someService.someField
}
link在此定义为any类型的类属性。
答案 0 :(得分:1)
在构造函数中定义函数会在您编写时创建一个类属性,并且仅将其分配给实例。
另一方面,类方法在原型上定义:
class A {
fn2: () => void;
constructor() {
this.fn2 = () => {
console.log("A.fn2");
};
}
fn1(): void {
console.log("A.fn1");
}
}
编译成:
var A = (function () {
function A() {
this.fn2 = function () {
console.log("A.fn2");
};
}
A.prototype.fn1 = function () {
console.log("A.fn1");
};
return A;
}());
如果要覆盖派生类中的函数,则使用实例函数会出现问题:
class B extends A {
constructor() {
super();
this.fn2 = () => {
super.fn2(); // Error: Only public and protected methods of the base class are accessible via the 'super' keyword
console.log("B.fn2");
};
}
fn1(): void {
super.fn1();
console.log("A.fn1");
}
}
您可以在分配新功能(this.fn2
)之前保存之前B
的参考,以便您有超级电话,但这不是非常舒服。
当然加上(如果您使用箭头功能),这些功能是开箱即用的this
权限。
由您来决定对您更重要的是什么,我更喜欢方法,如果我将它们作为回调传递,那么我只是bind them。
当您定期调用方法时,右this
应始终正确:
class A {
bound: () => void;
constructor() {
this.bound = () => {
console.log("bound: ", this);
};
}
unbound(): void {
console.log("unbound: ", this);
}
}
let a1 = new A();
a1.bound(); // A {}
a1.unbound(); // A {}
正如预期的那样,this
这里是A
的实例,但是:
function later(fn: Function) {
setTimeout(fn, 100);
}
later(a1.bound); // A {}
later(a1.unbound); // Window { ... }
正如您在此处所见,使用a1.unbound
调用setTimeout
时(或者如果您将其作为回调传递),则this
不是{{1}的实例}}。
这可以修复如下:
A