JS箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this
,arguments
,super
或new.target
。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
语法
基础语法
1 2 3 4 5 6 7 8 9 10
| (param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression
(singleParam) => { statements } singleParam => { statements }
() => { statements }
|
高级语法
1 2 3 4 5 6 7 8 9 10 11
| params => ({foo: bar})
(param1, param2, ...rest) => { statements } (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f();
|
描述
更短的函数
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
| var elements = [ 'Hydrogen', 'Helium', 'Lithium', 'Beryllium' ];
elements.map(function(element) { return element.length; });
elements.map((element) => { return element.length; });
elements.map(element => { return element.length; });
elements.map(element => element.length);
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX);
|
没有单独的this
在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值:
- 如果该函数是一个构造函数,this指针指向一个新的对象
- 在严格模式下的函数调用下,this指向
undefined
- 如果该函数是一个对象的方法,则它的this指针指向这个对象
- 等等
1 2 3 4 5 6 7 8 9 10 11 12
| function Person() { this.age = 0;
setInterval(function growUp() { this.age++; }, 1000); }
var p = new Person();
|
或者,可以创建绑定函数,以便将预先分配的this
值传递到绑定的目标函数。
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
。因此,在下面的代码中,传递给setInterval
的函数内的this
与封闭函数中的this
值相同:
1 2 3 4 5 6 7 8 9
| function Person(){ this.age = 0;
setInterval(() => { this.age++; }, 1000); }
var p = new Person();
|
通过 call
或 apply
调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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)); console.log(adder.addThruCall(1));
|
不绑定arguments
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var arguments = [1, 2, 3]; var arr = () => arguments[0];
arr();
function foo(n) { var f = () => arguments[0] + n; return f(); }
foo(1); foo(2); foo(3); foo(3,2);
|
在大多数情况下,使用剩余参数是相较使用arguments
对象的更好选择。
1 2 3 4 5 6 7 8 9 10 11
| function foo(arg) { var f = (...args) => args[0]; return f(arg); } foo(1);
function foo(arg1,arg2) { var f = (...args) => args[1]; return f(arg1,arg2); } foo(1,2);
|
使用箭头函数作为方法
1 2 3 4 5 6 7 8 9 10 11 12
| 'use strict'; var obj = { i: 10, b: () => console.log(this.i, this), c: function() { console.log( this.i, this) } } obj.b();
obj.c();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 'use strict'; var obj = { a: 10 };
Object.defineProperty(obj, "b", { get: () => { console.log(this.a, typeof this.a, this); return this.a+10; } });
obj.b;
|
使用 new 操作符
1 2
| var Foo = () => {}; var foo = new Foo();
|
使用prototype属性
1 2
| var Foo = () => {}; console.log(Foo.prototype);
|
函数体
1 2 3 4 5
| var func = x => x * x;
var func = (x, y) => { return x + y; };
|
函数体
记住用params => {object:literal}
这种简单的语法返回对象字面量是行不通的。
1 2 3 4 5
| var func = () => { foo: 1 };
var func = () => { foo: function() {} };
|
这是因为花括号({}
)里面的代码被解析为一系列语句(即 foo
被认为是一个标签,而非对象字面量的组成部分)。
所以,记得用圆括号把对象字面量包起来:
1
| var func = () => ({foo: 1});
|
换行
箭头函数在参数和箭头之间不能换行。
但是,可以通过在 ‘=>’ 之后换行,或者用 ‘( )’、’{ }’来实现换行,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var func = (a, b, c) => 1;
var func = (a, b, c) => ( 1 );
var func = (a, b, c) => { return 1 };
var func = ( a, b, c ) => 1;
|
解析顺序
1 2 3 4 5 6 7 8
| let callback;
callback = callback || function() {};
callback = callback || () => {};
callback = callback || (() => {});
|