ES6 教程:JavaScript 中箭头函数的完整介绍

入门

在 JavaScript ES6 之前,有几种声明函数的方法,可以是函数声明,如下所示:

function add(a, b) {
    return a + b;
}
console.log(add(2, 3))

或者用函数表达式:

var add = function(a, b) {
    return a + b;
}
console.log(add(2, 3))

箭头函数语法

现在,让我们将上面的两个函数转换为箭头函数,如下所示:

var add = (a, b) => {
    return a + b;
}
console.log(add(2, 3)); 

我们完全摆脱了function关键字,而是使用了=>看起来像箭头的语法,所以人们称之为“箭头函数”或“胖箭头函数”(不知道为什么它是胖的)。

让我们分解这个箭头函数的语法。首先,箭头函数需要是函数表达式,不能像普通函数那样单独放置。参数像普通函数一样在括号内传递。接下来,=>表示这是一个箭头函数,后面是函数体。我们像普通函数一样调用箭头函数。这是一般语法:

(param1, param2, …, paramN) => { statements } 
(param1, param2, …, paramN) => expression
// equivalent to: => { return expression; }

// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }

// The parameter list for a function with no parameters should be written with a pair of parentheses.
() => { statements }

带参数的箭头函数:

var myFunction = (para1, para2) => {
    // do something
}

如果你的函数只有一个表达式,你可以省略大括号和return关键字,并在一行上写一个完整的函数:

var myFunction = (para1, para2) => para1 + para2;

这样做时,箭头函数允许您有一个隐式 return,这意味着在调用没有 return 关键字的函数时将返回表达式。

var myFunction = (para1, para2) => para1 + para2;
myFunction(2, 3); // 5

var greeting = name => "Hello, my name is " + name;
greeting('Nam'); // Hello, my name is Nam

这些功能等于:

var myFunction = (para1, para2) => { return para1 + para2; }
myFunction(2, 3); // 5
var greeting = name => { return "Hello, my name is " + name; }
greeting('Nam'); // Hello, my name is Nam

如果你在括号内写了一段代码来包含你的函数体,即使它只是一条语句,如果你想返回一些东西,你仍然必须显式地使用 return 关键字。

如果您想隐式返回一个对象,请确保将其包装在括号内以避免混淆:

var test = () => { name: 'Jessica' };
test(); // undefined

// OK
var test = () => ({ name: 'Jessica' })
test(); // { name: 'Jessica' }

当函数只有一个参数时,围绕它的括号是可选的:


var square = num => num * num;
// OK, also
var square = (num) => num * num;

如果函数有两个或两个以上的参数,括号是强制性的,同样的规则适用于没有参数的函数:

var a = (para1, para2) => {
    // do something
}

var b = (para1, para2, para3) => {
    // do something
}

var c = () => {
    // do something
}

箭头函数也支持 ES6 中带有 rest 和 default 参数的一些高级语法:

(param1, param2, ...rest) => { statements }

var multiply = (a, b, ...c) => {
    var accumulator = a * b;
    for (var i of c) {
        accumulator *= i;
    }
    return accumulator;
};
multiply(1, 2, 3, 4, 5); // 120

(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { 
statements }

var x = (para1 = 'JavaScript') => {
    return "I want to learn " + para1;
}
x(); // I want to learn JavaScript
x('HTML'); // I want to learn HTML

我们将在接下来的文章中了解更多关于扩展运算符、休息和默认参数的信息。

箭头函数和“THIS”关键字

“this”关键字可能是 JavaScript 中最难以捉摸的部分之一。我已经写了一篇关于箭头函数中“ this ”关键字的综合文章。查看这篇文章以了解有关“ this”关键字的更多信息。

一般来说,对于常规函数,我们总是必须跟踪“this”上下文并记住正确绑定它,当我们有多个嵌套函数时问题会很麻烦。使用箭头函数,使用“this”关键字更容易,因为箭头函数没有自己的绑定到“this”,如果在箭头函数内部访问“this”,它是从外部获取的。

var person = {
    name: 'Zeep',
    tasks: ['sweep the floor', 'clean the room', 'wash the dishes', 'take out the garbage'],
    doing: function() {
        this.tasks.forEach(task => {
            console.log(this.name + " needs to " + task);
        });
    }
}
person.doing();
/*
Zeep needs to sweep the floor
Zeep needs to clean the room
Zeep needs to wash the dishes
Zeep needs to take out the garbage
*/

在上面的代码段中,我们看到this.nameconsole里面有,由于箭头函数没有自己绑定到this,它会去外面找,在这里找到doing()属于person Object的方法,然后this在这种情况下,将引用person对象。否则对于常规函数,函数this内部总是引用一个全局对象,即窗口对象。因此,如果我们用常规函数更改箭头函数,我们会得到不同的结果:

var person = {
    name: 'Zeep',
    tasks: ['sweep the floor', 'clean the room', 'wash the dishes', 'take out the garbage'],
    doing: function() {
        this.tasks.forEach(function(task) {
// this now refers to the window object, and this.name is not specified, hence 'undefined' will be returned.
            console.log(this.name + " needs to " + task);
        });
    }
}
person.doing();
/* 
undefined needs to sweep the floor
undefined needs to clean the room
undefined needs to wash the dishes
undefined needs to take out the garbage
*/

将箭头函数仅用作函数或非对象方法时也许是有益的,但在为对象创建方法方面,箭头函数不适合:

var book = {
    title: 'Thinking, Fast and Slow',
    author: 'Daniel Kahneman',
    display: () => {
        return this.title + " is written by " + this.author;
    }
}
book.display();
// undefined is written by undefined

箭头函数不能用作构造函数。它们不能用new关键字调用。

var Book = (title, author) => {
    this.title = title;
    this.author = author;
}

var instance = new Book('To Kill a Mockingbird', 'Harper Lee'); // TypeError

处理事件时,this函数内部的值应该是动态的,因此箭头函数在这种情况下并不理想。

var element = document.querySelector('.elem');
element.addEventListener('click', () => {
    // this === Window
})
element.addEventListener('click', function() {
    // this === element
})

箭头函数没有“参数”

在 JavaScript 中,arguments 是一个 Array可在函数内部访问的类似对象,其中包含传递给该函数的参数值。箭头函数没有自己的“this”绑定,也没有参数对象。arguments 继承自它们的父函数,例如“this”。

// OK with regular function
var temp = function() {
    var arr = Array.from(arguments);
    return arr;
}
temp(1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]

// Not so OK with arrow function

var temp = () => {
    var arr = Array.from(arguments);
    return arr;
}
temp(1, 2, 3, 4, 5); // Error

数组操作中的箭头函数

现在我们已经学习了箭头函数的基本语法并看到了它的一些用例。但在大多数情况下,箭头函数通常用于通过某些方法进行数组操作,例如map()filter()reduce()

例如,我们有一个对象数组,我们将使用箭头函数和上面列出的一些方法来操作数组。

var fruits = [
    {
        name: 'pear',
        price: 20
    },
    {
        name: 'grape',
        price: 15
    },
    {
        name: 'apple',
        price: 25
    }
];

现在让我们获取水果的名称:

fruits.map(fruit => fruit.name); 
/*
pear
grape
apple
*/

检查水果的价格大于或等于 20:

fruits.filter(fruit => fruit.price >= 20);
// [ { name: 'pear', price: 20 }, { name: 'apple', price: 25 } ]

总结一下水果的价格:

fruits.reduce((accumulator, fruit) => accumulator + fruit.price, 0); // 60

正如我们所看到的,在这种情况下使用箭头函数使代码看起来非常清晰和简洁。

带有回调和Promise的箭头函数

在使用异步或 Promise 时,使用传统 ES5 的代码通常包含许多函数和返回关键字。因此,异步代码也是使用箭头函数使代码更简洁易读的好地方。这是一个在 ES5 中链接承诺的简单示例:

aAsync()
    .then(function () { return bAsync(); })
    .then(function () { return cAsync(); })
    .done(function () { finish(); });

使用 ES6,上面的这段代码可以翻译成更短更简洁的版本:

Async().then(() => bAsync()).then(() => (Async()).done(() => finish);

什么时候不应该使用箭头函数

箭头函数通常非常棒,但我们仍然不能完全用箭头函数代替常规函数。如前所述,总结一下,有些情况下你不应该使用箭头函数:

  • 对象方法
  • DOM 事件
  • 原型方法
  • 当您需要使用参数对象时

如果您愿意,可以在所有其他场合使用箭头功能。

总结起来

总的来说,箭头函数是 ES6 最受青睐的特性之一,在箭头函数的帮助下,你的代码可以看起来更加整洁和简洁。此类函数通常用于数组操作、异步代码和许多其他场景。在某些情况下它不能代替常规功能。它没有thisargument, 不能作为构造函数工作,并且使用 new 关键字调用它会发生错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Meta.Qing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值