箭头函数

简介:
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。

JavaScript Demo: Functions =>

1
2
3
4
5
6
7
8
9
var materials = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];

console.log(materials.map(material => material.length));
// expected output: Array [8, 6, 7, 9]

Syntax

Basic syntax
1
2
3
4
5
6
7
8
9
10
11
(param1, param2, …, paramN) => { statements } 
(param1, param2, …, paramN) => expression
// equivalent to: => { return expression; }


//如果只有一个参数,则括号可以省略:
(singleParam) => { statements }
singleParam => { statements }

//参数列表中没有参数的函数的括号不可省略:
() => { statements }
Advanced syntax
1
2
3
4
5
6
7
8
9
10
// 函数体加括号,返回对象字面量表达式(?function类型对象,加括号与不加括号的区别是,):
params => ({foo: bar})

//支持省略参数和指定参数
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }

//同样支持参数列表解构
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6

描述

引入箭头函数的两个原因:简短的函数写法和没有this的干扰

简短的函数写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];

elements.map(function(element) {
return element.length;
}); // 返回数组: [8, 6, 7, 9]

//上面的一般的函数写法可以改为以下箭头函数的写法:
elements.map((element) => {
return element.length;
}); // [8, 6, 7, 9]

// 当只有一个参数时,包裹参数的括号可省略:
elements.map(element => {
return element.length;
}); // [8, 6, 7, 9]

//当函数体只有一条语句,且为`return`语句,可以省略 `return` 的同时省略函数体的大括号
elements.map(element => element.length); // [8, 6, 7, 9]

// In this case, because we only need the length property, we can use destructuring parameter:
// Notice that the `length` corresponds to the property we want to get whereas the
// obviously non-special `lengthFooBArX` is just the name of a variable which can be changed
// to any valid variable name you want
elements.map(({ length :lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

// This destructuring parameter assignment can also be written as seen below. However, note that in
// this example we are not assigning `length` value to the made up property. Instead, the literal name
// itself of the variable `length` is used as the property we want to retrieve from the object.
elements.map(({ length }) => length); // [8, 6, 7, 9]
没有this的干扰

除了箭头函数,每个函数基于调用方式定义了自己的this值:

  • 一个构造函数的this值是其生成的一个新对象
  • 在严格模式下,函数调用的this值是undefined
  • 如果函数作为对象的方法调用,那么this值就是这个对象
  • 等等

事实证明,面向对象的编程风格并不理想。

1
2
3
4
5
6
7
8
9
10
11
12
function Person() {
// 构造函数 Person() 定义了自己的 this ,值为它生成的一个实例.
this.age = 0;

setInterval(function growUp() {
//在非严格模式中,growUp()函数定义的this值为全局对象(因为growUp()在全局环境中执行),
//和 Person() 构造函数所定义的this值不同。
this.age++;
}, 1000);
}

var p = new Person();

在ECMAScript 3/5中,由this引发的这种问题可以通过将this值赋给变量来解决:

1
2
3
4
5
6
7
8
9
function Person() {
var that = this;
that.age = 0;

setInterval(function growUp() {
// 回调中所使用的that变量指向的正是我们期望的对象
that.age++;
}, 1000);
}

参考自:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions