TypeScript入门教程 之 箭头函数

TypeScript入门教程 之 箭头函数

 

亲切地称为粗箭头(因为->是细箭头并且=>是粗箭头),也被称为lambda函数(由于其他语言)。另一个常用功能是胖箭头功能()=>something。粗箭头的动机是:

  1. 您不需要继续打字 function
  2. 它从字面上捕获了 this
  3. 它从字面上捕获了 arguments

对于声称具有功能性的语言,在JavaScript中您经常会键入function很多内容。粗箭头使您轻松创建函数

var inc = (x)=>x+1;

this传统上一直是JavaScript的痛点。正如一个明智的人曾经说过的:“我讨厌JavaScript,因为它会很容易失去this所有含义。” 粗箭头通过捕获this周围上下文的含义来修复它。考虑这个纯JavaScript类:

function Person(age) {
    this.age = age;
    this.growOld = function() {
        this.age++;
    }
}
var person = new Person(1);
setTimeout(person.growOld,1000);

setTimeout(function() { console.log(person.age); },2000); // 1, should have been 2

如果您this在功能内的浏览器中运行此代码,则将指向该位置,window因为window它将执行该growOld功能。解决的方法是使用箭头功能:

function Person(age) {
    this.age = age;
    this.growOld = () => {
        this.age++;
    }
}
var person = new Person(1);
setTimeout(person.growOld,1000);

setTimeout(function() { console.log(person.age); },2000); // 2

之所以起作用,this是因为箭头功能从功能体外部捕获了对它的引用。这等效于以下JavaScript代码(如果没有TypeScript,这将是您自己编写的代码):

function Person(age) {
    this.age = age;
    var _this = this;  // capture this
    this.growOld = function() {
        _this.age++;   // use the captured this
    }
}
var person = new Person(1);
setTimeout(person.growOld,1000);

setTimeout(function() { console.log(person.age); },2000); // 2

请注意,由于您使用的是TypeScript,因此您可以在语法上更加精巧,并结合箭头和类:

class Person {
    constructor(public age:number) {}
    growOld = () => {
        this.age++;
    }
}
var person = new Person(1);
setTimeout(person.growOld,1000);

setTimeout(function() { console.log(person.age); },2000); // 2

关于这个模式的甜蜜视频video

提示:箭头功能需要

除了简洁的语法,你只需要使用脂肪箭头,如果你打算给函数给别人打电话。有效:

var growOld = person.growOld;
// Then later someone else calls it:
growOld();

如果您要自己称呼它,即

person.growOld();

那么this它将是正确的调用上下文(在此示例中person)。

提示:箭头功能危险

实际上,如果要this 成为调用上下文,则不应使用arrow函数。jQuery,下划线,mocha等库使用的回调就是这种情况。如果文档中提到函数,this那么您可能应该只使用a function而不是粗箭头。同样,如果您打算使用,arguments请不要使用箭头功能。

提示:带有库的箭头函数使用 this

许多库都这样做,例如jQueryiterables(一个示例https://api.jquery.com/jquery.each/)将this用来将当前正在迭代的对象传递给您。在这种情况下,如果要访问传递的库this以及周围的上下文,只需像使用_self缺少箭头功能一样使用temp变量即可。

let _self = this;
something.each(function() {
    console.log(_self); // the lexically scoped value
    console.log(this); // the library passed value
});

提示:箭头函数和继承

箭头函数作为类的属性可以很好地与继承一起工作:

class Adder {
    constructor(public a: number) {}
    add = (b: number): number => {
        return this.a + b;
    }
}
class Child extends Adder {
    callAdd(b: number) {
        return this.add(b);
    }
}
// Demo to show it works
const child = new Child(123);
console.log(child.callAdd(123)); // 246

但是,super当您尝试覆盖子类中的函数时,它们不适用于关键字。属性继续this。由于只有一个this这样的函数不能参与调用supersuper仅适用于原型成员)。您可以通过在子项中覆盖该方法之前创建该方法的副本来轻松解决该问题。

class Adder {
    constructor(public a: number) {}
    // This function is now safe to pass around
    add = (b: number): number => {
        return this.a + b;
    }
}

class ExtendedAdder extends Adder {
    // Create a copy of parent before creating our own
    private superAdd = this.add;
    // Now create our override
    add = (b: number): number => {
        return this.superAdd(b);
    }
}

提示:快速返回对象

有时您需要一个仅返回简单对象文字的函数。但是,类似

// WRONG WAY TO DO IT
var foo = () => {
    bar: 123
};

JavaScript运行时将其解析为包含JavaScript标签(由于JavaScript规范)。

如果那没有意义,请放心,因为TypeScript会出现一个不错的编译器错误,说“未使用的标签”。标签是一种古老的(几乎未使用的)JavaScript功能,作为现代的GOTO可以忽略(经验丰富的开发人员认为它很糟糕bad)

您可以通过以下方式修复对象文字()

// Correct 🌹
var foo = () => ({
    bar: 123
});

 

翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/arrow-functions.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值