Gid*_*eon 13 typescript ecmascript-6 angular
在Angular中,在技术上可以将类方法编写为ES2015箭头函数,但我从未真正见过有人这样做过.以这个简单的组件为例:
@Component({
selector: 'sample'
})
export class SampleComponent {
arrowFunction = param => {
// Do something
};
normalFunction(param) {
// Do something
}
}
Run Code Online (Sandbox Code Playgroud)
这没有任何问题.有什么不同吗?为什么我应该或不应该使用它?
Est*_*ask 25
本React答案中的要点在Angular,任何其他框架或vanilla JavaScript/TypeScript中仍然有效.
类原型方法是ES6,类箭头方法不是.箭头方法属于类字段提案,而不是现有规范的一部分.它们在TypeScript中实现,也可以使用Babel进行转换.
通常最好使用原型而method() { ... }不是箭头,method = () => { ... }因为它更灵活.
arrow方法提供的唯一真正机会是它可以无缝地用作回调:
class Class {
method = () => { ... }
}
registerCallback(new Class().method);
Run Code Online (Sandbox Code Playgroud)
如果原型方法应该用作回调,它应该另外绑定,这应该最好在构造函数中完成:
class Class {
constructor() {
this.method = this.method.bind(this);
}
method() { ... }
}
registerCallback(new Class().method);
Run Code Online (Sandbox Code Playgroud)
类似装饰器bind-decorator可以在TypeScript和ES Next中使用,为构造函数中的方法绑定提供更简洁的替代方法:
import bind from 'bind-decorator';
class Class {
@bind
method() { ... }
}
Run Code Online (Sandbox Code Playgroud)
Arrow方法也限制子类使用箭头方法,否则不会覆盖它们.如果忽略箭头,则会产生问题:
class Parent {
method = () => { ... }
}
class Child extends Parent {
method() { ... } // won't override Parent method
}
Run Code Online (Sandbox Code Playgroud)
super.method()在子类中使用是不可能的,因为它super.method引用了Parent.prototype.method,它不存在:
class Parent {
method = () => { ... }
}
class Child extends Parent {
method = () => {
super.method(); // won't work
...
}
}
Run Code Online (Sandbox Code Playgroud)
原型方法可以有效地用于mixins.Mixins可用于多重继承或修复TypeScript方法可见性中的问题.
由于箭头方法在类原型上不可用,因此无法从类外部访问:
class Parent {
method = () => { ... }
}
class Child extends OtherParent { ... }
Object.assign(Child.prototype, Parent.prototype) // method won't be copied
Run Code Online (Sandbox Code Playgroud)
原型方法提供的一个有价值的特性是它们可以在类实例化之前访问,因此它们可以在测试中进行间谍或模拟,即使它们在构造后立即被调用:
class Class {
constructor(arg) {
this.init(arg);
}
init(arg) { ... }
}
spyOn(Class.prototype, 'init').and.callThrough();
const object = new Class(1);
expect(object.init).toHaveBeenCalledWith(1);
Run Code Online (Sandbox Code Playgroud)
当方法是箭头时,这是不可能的.
TL; DR:原型和箭头类方法之间的选择似乎是一种品味问题,但实际上使用原型方法更具有远见卓识.您通常可能希望避免箭头类方法,除非您确定它们不会造成任何不便.bind如果将它们作为回调传递,请不要忘记使用原型方法.