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

查看:24
本文介绍了我应该在 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 answer 中的观点仍然存在在 Angular、任何其他框架或 vanilla 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.

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

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 方法限制子类也使用箭头方法,否则它们不会被覆盖.如果忽略箭头,则会产生问题:

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
    ...
  }
}

混合

原型方法可以有效地用于mixin.Mixin 可用于多重继承或修复 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.

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

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