我应该在Angular的类中将方法编写为箭头函数吗 [英] Should I write methods as arrow functions in Angular's class

查看:118
本文介绍了我应该在Angular的类中将方法编写为箭头函数吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Angular中,可以将类方法编写为ES2015箭头函数,但实际上我从未见过有人这样做.以这个简单的组件为例:

In Angular it's technically possible to write class methods as ES2015 arrow functions, but I have never actually seen someone do it. Take this simple component for instance:

@Component({
  selector: 'sample'
})
export class SampleComponent {
  arrowFunction = param => {
    // Do something
  };
  normalFunction(param) {
    // Do something
  }
}

这有效,没有任何问题.有什么区别吗?为什么我不应该使用这个?

This works without any issues. Are there any differences? And why should or shouldn't I use this?

推荐答案

此React答案中提出的要点仍然在Angular,任何其他框架或原始JavaScript/TypeScript中有效.

The points made in this React answer are still valid in Angular, any other framework or vanilla JavaScript/TypeScript.

类原型方法是ES6,而类箭头方法不是.箭头方法属于类字段提案,而不是现有规范的一部分.它们在TypeScript中实现,也可以与Babel一起进行编译.

Class prototype methods are ES6, class arrow methods aren't. Arrow methods belong to class fields proposal and not a part of existing specs. They are implemented in TypeScript and can be transpiled with Babel as well.

通常,使用原型method() { ... }比使用箭头method = () => { ... }更可取,因为它更灵活.

It's generally preferable to use prototype method() { ... } than arrow method = () => { ... } because it's more flexible.

arrow方法提供的唯一真正机会是它可以无缝用作回调:

The only real opportunity that arrow method provides is that it it can be seamlessly used as a callback:

class Class {
  method = () => { ... }
}

registerCallback(new Class().method);

如果应将原型方法用作回调,则应另外绑定它,这最好在构造函数中完成:

If prototype method should be used as a callback it should be additionally bound, this should be preferably be done in constructor:

class Class {
  constructor() {
    this.method = this.method.bind(this);
  }

  method() { ... }
}

registerCallback(new Class().method);

诸如 bind-decorator 之类的装饰器可以在TypeScript和ES Next中使用,以提供构造函数中方法绑定的更简洁替代方法:

A decorator like bind-decorator can be used in TypeScript and ES Next to provide more concise alternative to method binding in constructor:

import bind from 'bind-decorator';

class Class {
  @bind
  method() { ... }
}

继承

Arrow方法将子类也限制为使用arrow方法,否则它们不会被覆盖.如果忽略了箭头,则会产生问题:

Inheritance

Arrow method restricts child classes to use arrow methods too, otherwise they won't be overridden. This creates a problem if an arrow was overlooked:

class Parent {
  method = () => { ... }
}

class Child extends Parent {
  method() { ... } // won't override Parent method
}

不可能在子类中使用super.method(),因为super.method引用了Parent.prototype.method,它不存在:

It's not possible to use super.method() in child class because super.method refers to Parent.prototype.method, which doesn't exist:

class Parent {
  method = () => { ... }
}

class Child extends Parent {
  method = () => {
    super.method(); // won't work
    ...
  }
}

Mixins

原型方法可以在mixins中有效地使用. Mixins对于多重继承或修复TypeScript方法可见性中的问题很有用.

Mixins

Prototype methods can be efficiently used in mixins. Mixins are useful for multiple inheritance or to fix problems in TypeScript method visibility.

由于箭头方法在类原型上不可用,因此无法从类外部访问它:

Since arrow method isn't available on class prototype, it can't be reached from outside the class:

class Parent {
  method = () => { ... }
}

class Child extends OtherParent { ... }
Object.assign(Child.prototype, Parent.prototype) // method won't be copied

测试

原型方法提供的一个有价值的功能是,它们可以在类实例化之前访问,因此即使在构造之后立即调用它们,也可以在测试中对其进行监视或模拟:

Testing

A valuable feature that prototype methods provide is that they are accessible before class instantiation, thus they can be spied or mocked in tests, even if they are called right after construction:

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);

当方法是箭头时,这是不可能的.

This is not possible when a method is an arrow.

TL; DR:在原型方法和箭头类方法之间进行选择似乎是一个问题,但实际上使用原型方法是有远见的.您通常可能希望避免使用箭头类方法,除非您确定它们不会造成任何不便.如果您将它们作为回调传递,请不要忘记在原型方法上使用bind.

TL;DR: the choice between prototype and arrow class methods seems like a matter of taste, but in reality the use of prototype methods is more far-sighted. You may usually want to avoid arrow class methods, unless you are sure that they will cause no inconvenience. Don't forget to use bind on prototype methods if you pass them as callbacks.

这篇关于我应该在Angular的类中将方法编写为箭头函数吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆