箭头函数
一、基础语法:
(参数1,参数2,...,参数N) => {函数声明} (参数1,参数2,...,参数N) => 表达式(单一) //相当于:(参数1,参数2,...,参数N) => {return 表达式;} // 当只有一个参数时,圆括号是可选的: (单一参数) => {函数声明} 单一参数 => {函数声明} // 没有参数的函数应该写成一对圆括号。 () => {函数声明}
二、高级语法:
//加括号的函数体返回对象字面表达式: 参数=> ({foo: bar}) //支持剩余参数和默认参数 (参数1, 参数2, ...rest) => {函数声明} (参数1 = 默认值1,参数2, …, 参数N = 默认值N) => {函数声明} //同样支持参数列表解构 let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
三、引入箭头函数的作用以及其他知识点:
引入箭头函数有两个方面的作用:更简短的函数并且不绑定this
1、更短的函数
var materials = [ 'Hydrogen', 'Helium', 'Lithium', 'Beryllium' ]; //返回数组materials中每个字符串的长度。 //ES5的写法 materials.map(function(material) { return material.length; }); // [8, 6, 7, 9] //ES6的写法 materials.map((material) => { return material.length; }); // [8, 6, 7, 9] materials.map(material => material.length); // [8, 6, 7, 9]
我们可以看到,ES6的写法相对于ES5的写法来说,省掉了function关键字。由于我们的处理函数只有一个参数,所以根据箭头函数的基础语法,我们可以省略参数的圆括号。又由于我们的处理函数只是return了一个表达式,所以我们还可以省略掉{}和return关键字。所以,箭头函数相对于ES5的传统函数要简短很多。
2、不绑定this
在箭头函数出现之前,每个新定义的函数都有它自己的 this值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被称为“对象方法”则为基础对象等)。This
被证明是令人厌烦的面向对象风格的编程。
function Person() { // Person() 构造函数定义 `this`作为它自己的实例. this.age = 0; setInterval(function growUp() { // 在非严格模式, growUp()函数定义 `this`作为全局对象, // 与在 Person()构造函数中定义的 `this`并不相同. this.age++; }, 1000); } var p = new Person();
在ECMAScript5中,通过将this
值分配给封闭的变量,可以解决this
问题。
function Person() { var that = this; that.age = 0; setInterval(function growUp() { // 回调引用的是`that`变量, 其值是预期的对象. that.age++; }, 1000); }
箭头函数不会创建自己的this
;它使用封闭执行上下文的this
值。因此,在下面的代码中,传递给setInterval
的函数内的this
与封闭函数中的this
值相同:
function Person(){ this.age = 0; setInterval(() => { this.age++; // |this| 正确地指向person 对象 }, 1000); } var p = new Person();
也就是说,使用箭头函数的时候,this的值的指向在任何时候都是清晰的。
3、箭头函数不能用做构造器,和new一起用会抛出错误
var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor
4、箭头函数没有prototype属性
var Foo = () => {}; console.log(Foo.prototype); // undefined
5、函数体
箭头函数可以有一个“简写体”或常见的“块体”。在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return
语句。
var func = x => x * x; // 简写函数 省略return 返回值是x*x的值 这个返回值是隐式的 var func = (x, y) => { return x + y; }; //常规编写 明确的返回值
6、返回对象字面量
记住用params => {object:literal}
这种简单的语法返回对象字面量是行不通的。
var func = () => { foo: 1 }; // Calling func() returns undefined! var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name
这是因为花括号({}
)里面的代码被解析为一系列语句(即 foo
被认为是一个标签,而非对象字面量的组成部分)。所以,记得用圆括号把对象字面量包起来:
var func = () => ({foo: 1});
7、换行
箭头函数在参数和箭头之间不能换行。
var func = () => 1; // SyntaxError: expected expression, got '=>'