ES6中增加了箭头函数,箭头函数是简写形式的函数表达式,即:使用箭头(=>)来定义函数。箭头函数拥有词法的作用域,且总是匿名函数。
1. 语法结构
基本语法:
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
//等同于
(param1, param2, …, paramN) => { return expression; }
// 如果只有一个参数,圆括号是可选的:
(singleParam) => { statements }
singleParam => { statements }
// 无参数的函数需要使用圆括号:
() => { statements }
高级语法:
// 返回对象字面量时应当用圆括号将其包起来:
params => ({foo: bar})
// 支持 Rest 参数 和 default 参数
(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
例如,对于如下一个箭头函数:
var f = v => v;
其相当于:
var f = function(v) {
return v;
};
几个箭头函数的使用示例:
// 一个空箭头函数,返回 undefined
let empty = () => {};
(() => "foobar")() // 返回 "foobar"
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
let max = (a, b) => a > b ? a : b;
// 数组的应用
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
2. 箭头函数介绍
箭头函数提供了更短的函数书写形式和this的词法解析。
2.1 更短的函数
更短的函数书写形式,可以使代码更为简洁:
var a = [
"niefengjun.cn",
"niefengjun.cn",
"yijiebuyi.com"
];
var a2 = a.map(function(s){ return s.length });
// 使用箭头函数代码量会相对减少
var a3 = a.map( s => s.length );
2.2 this的词法
在箭头函数出现之前,每个新定义的函数都有自己的this值。
- 构造函数的
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();
由于this指向的问题,在面向对象编程中会造成一定的问题,这被证明是非常恼人的事情。在ECMAScript 3/5中,可以使用另一个变量指向this,以达到想要的效果:
function Person() {
var self = this; // 将'self'变量指向'this'
self.age = 0;
setInterval(function growUp() {
// 回调中的 `self` 变量可以正常指向期望的那个对象了
self.age++;
}, 1000);
}
箭头函数总是匿名函数,所以没有自身的作用域。箭头函数会捕获上下文中的this值,做为自己的this值。箭头函数可以很好的解决上面的问题:
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // 'this'正确地指向了 person 对象
}, 1000);
}
var p = new Person();
严格模式
箭头函数中,this作用域是词法层面的,严格模式中与this的相关的规则都将被忽略,除this外的其它的规则不变。
var f = () => {'use strict'; return this};
f() === window; // ture,全局对象
使用call或apply调用
this已经在词法层面完成了绑定,通过call或apply方法调用一个函数时,只是传入参数:
var adder = {
base : 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base : 2
};
return f.call(b, a);
}
};
console.log(adder.add(1)); // 输出 2
console.log(adder.addThruCall(1)); // 仍然输出 2
2.3 arguments词法
箭头函数没有自己的arguments。arguments.length、arguments[0]等都指向其词法所在作用域的arguments对象。
var arguments = 42;
var arr = () => arguments;
arr(); // 42
function foo() {
var f = () => arguments[0];
return f(2);
}
foo(1); // 1
