迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > TypeScript >

TypeScript 经典函数与箭头方法

作者:迹忆客 最近更新:2022/08/27 浏览次数:

何时使用不同的符号。

经典函数和箭头方法非常相似,但语法不同。

从 ES2015 开始,有一种箭头函数语法可用:它具有轻量级语法,并且使用匿名函数而无需显式返回。

const result = (person) => {
  return `Good afternoon, ${person}`;
}
// RxJs method "find" which looks for records in array:
const preSelectedTariff = this._tariffs?.find(tariff => tariff.tariffUniqueId === this.selectedTariff?.tariffUniqueId);

Lambda 是一个小型匿名函数。 它可以接受任意数量的参数,但只能有一个表达式。 但是匿名会产生一些问题:

1. 更难调试

当我们收到错误时,我们将无法跟踪函数的名称或发生错误的确切行号。

2. 块作用域

在逻辑上与经典函数一起工作。 函数可以按任何顺序声明,应用程序将以任何方式工作。

callMyFunction();
function callMyFunction() {
  console.log(`Rnd number ${getAnother(1000)}`);
}
function getAnother(max: number) {
  return Math.floor(Math.random() * (max + 1));
}

这是命令式编程与函数式编程。 他们每个人都有自己的优势。 但是由于块作用域,函数应该按照它们出现的顺序来声明。

tryToCallInWrongOrder();
const tryToCallInWrongOrder = () => {
  console.log(`Trying to call the function ${getAnother(1001)}`);
}
function getAnother(max: number) {
  return Math.floor(Math.random() * (max + 1));
}

3. 没有自引用

如果我们的函数需要具有自引用,那么它将不起作用。 例如,它可以是递归或事件处理程序。


不应该使用 箭头方法的场景:

1. 对象里的方法

当我们在对象内部使用箭头函数时,它从外部范围继承 this 值,而不是从本地范围, 并且 count 变量不可用。

const counter = {
  count: 0,
  getFollowing: () => this.count+1,
  getCurrent: () => this.count
};
console.log( counter.getFollowing() );

在 JavaScript 中:使用 arguments 对象的函数。

箭头函数没有参数对象。 因此,如果我们有一个使用 arguments 对象的函数,则不能使用箭头函数。

const concat = (separator) => {
    let args = Array.prototype.slice.call(arguments, 1);
    return args.join(separator);
}

但是参数在常规函数中起作用:

function getChar() {
  return Array.prototype.slice.call(arguments,0,1);
}
console.log(getChar('a','b','c'));
// 或使用这样的分隔符:
function concat(separator) {
    let args = Array.prototype.slice.call(arguments, 2);
    return args.join(separator);
}
console.log( concat(',', 'A', 'B', 'C', 'D', 'E') );

当它使我们的代码难以理解时

常规函数提供 100% 清晰的输入参数和输出类型语法。 但是箭头方法对于输入类型和输出内容并不那么简单。 它是函数式编程方法。


该方法的两种符号之间的好处区别是什么?

1. 继承

箭头方法不允许在子类中继承相同的方法,它不会被覆盖。

class Parent {
  method = () => { console.log("Parent method"); }
}
class Child extends Parent {
  method = () => {  // 不会覆盖 Parent 方法
    super.method();
    // 不起作用,因为引用了不存在的 Parent.prototype.method
  }
}

2. new

常规函数是可构造的,可以使用 new 关键字调用它们。

const kv = new Map();

kv.set("Test msg", "Unknown");
kv.set("", "Unknown");
kv.set(null, "Unknown");
kv.forEach((value, key) => {
  expect(new RequestTypePipe().transform(key)).toEqual(value);
});

但是,箭头函数永远不能用作构造函数。 因此,它们永远不能用 new 关键字调用:

let add = (x: number, y: number) => console.log(x + y);
const error = new add(1, 1); // TypeError: 'add' is not a constructor
const result = add(1000, 1);

new 关键字提供了创建实例的清晰方法:

private readonly unsubscribe$: Subject<void> = new Subject();
private chargeSubscription: Subscription;
ngOnDestroy(): void {
  this.unsubscribe$.next();
  this.unsubscribe$.complete();
}
private readonly subscribeToQuotation = (): void => {
  this.chargeSubscription = this.myService()
    .pipe(takeUntil(this.unsubscribe$))
    .subscribe(charge => this.handleCharge(charge));
};

3. 参数绑定

const mapToLocationCode = (geo: Geo): string => geo?.code || "";
return mapToLocationCode(houseObject.geo);

但是,如果要访问箭头函数中的参数,可以使用 rest 运算符:

var arrowFunction = (...args) => {
    console.log(...args)
}
arrowFunction("my", "additional", "argument");

4. 隐式返回

经典函数使用 return 关键字来返回值。 如果错过了,则该函数将返回未定义。

箭头函数减少代码,提供隐式返回,使代码更干净。

let message = () => 1001;
const result = (message: () => void) => { console.log(message) };
// 将message 作为参数传给result方法
result(message); 

这来自 Kotlin 世界:如果没有参数 - 使用下划线:

let myArrowMethod = _ => console.log("Arrow Method");

5. this

ES6 箭头方法没有 this,不能绑定 this 关键字。 我们所能做的就是引用外部范围变量。

const thename = "Alex";
let nameObject = {
  name : "Another Alex",
  arrowMethod: () => {
    console.log('arrowFunc: ' + thename);  //access to outer variabl
  },
  classicFunction() {
    console.log('classicFunction: ' + this.name); 
  }   
}
nameObject.arrowMethod();
nameObject.classicFunction();

常规函数用自己的 this 定义创建一个对象和一个作用域,但与箭头方法不同。

let currentValue: { value: string };
// 经典函数
const saveFunction = function (data: any) {
  currentValue = { 'value': data };
  console.log(currentValue);
}
// 箭头函数
const arrowMethod = (data: any) => {
  currentValue = { 'value': data };
  console.log(currentValue);
}
saveFunction('method');
arrowMethod('arrow');

总结

还有很多其他的差异,我描述了其中的主要差异。 很难说,何时选择其中一种方法。 函数式编程需要更少的代码,经常使用箭头方法!

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 TypeScript 中返回一个 Promise

发布时间:2023/03/19 浏览次数:182 分类:TypeScript

本教程讨论如何在 TypeScript 中返回正确的 Promise。这将提供 TypeScript 中 Returns Promise 的完整编码示例,并完整演示每个步骤。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便