TypeScript 经典函数与箭头方法
何时使用不同的符号。
经典函数和箭头方法非常相似,但语法不同。
从 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');
总结
还有很多其他的差异,我描述了其中的主要差异。 很难说,何时选择其中一种方法。 函数式编程需要更少的代码,经常使用箭头方法!
相关文章
在 AngularJs 中设置 Select From Typescript 的默认选项值
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程提供了在 AngularJs 中从 TypeScript 中设置 HTML 标记选择的默认选项的解释性解决方案。
在 Angular 中使用 TypeScript 的 getElementById 替换
发布时间:2023/04/14 浏览次数:153 分类:Angular
-
本教程指南提供了有关使用 TypeScript 在 Angular 中替换 document.getElementById 的简要说明。这也提供了在 Angular 中 getElementById 的最佳方法。
在 TypeScript 中使用 try..catch..finally 处理异常
发布时间:2023/03/19 浏览次数:181 分类:TypeScript
-
本文详细介绍了如何在 TypeScript 中使用 try..catch..finally 进行异常处理,并附有示例。
在 TypeScript 中使用 declare 关键字
发布时间:2023/03/19 浏览次数:97 分类:TypeScript
-
本教程指南通过特定的实现和编码示例深入了解了 TypeScript 中 declare 关键字的用途。
在 TypeScript 中 get 和 set
发布时间:2023/03/19 浏览次数:172 分类:TypeScript
-
本篇文章演示了类的 get 和 set 属性以及如何在 TypeScript 中实现它。
在 TypeScript 中格式化日期和时间
发布时间:2023/03/19 浏览次数:161 分类:TypeScript
-
本教程介绍内置对象 Date() 并讨论在 Typescript 中获取、设置和格式化日期和时间的各种方法。
在 TypeScript 中返回一个 Promise
发布时间:2023/03/19 浏览次数:182 分类:TypeScript
-
本教程讨论如何在 TypeScript 中返回正确的 Promise。这将提供 TypeScript 中 Returns Promise 的完整编码示例,并完整演示每个步骤。
在 TypeScript 中定义函数回调的类型
发布时间:2023/03/19 浏览次数:221 分类:TypeScript
-
本教程说明了在 TypeScript 中为函数回调定义类型的解决方案。为了程序员的方便和方便,实施了不同的编码实践指南。
在 TypeScript 中把 JSON 对象转换为一个类
发布时间:2023/03/19 浏览次数:110 分类:TypeScript
-
本教程演示了如何将 JSON 对象转换为 TypeScript 中的类。