箭头函数的语法
箭头函数的语法多变,根据实际使用场景有多种形式。所有的变种都由函数参数、箭头、函数体组成,根据使用的需求,参数和函数体可分别采取多种不同形式。举个例子:
let reflect = value => value;
// 实际上相当于:
let reflect = function(value) {
return value;
};
当箭头函数只有一个参数时,可以直接写参数名,箭头紧随其后,箭头右侧的表达式被求值后便立即返回。即使没有显示的返回语句,这个箭头函数也可以返回出传入的第一个参数,不需要更多的语法铺垫。
如果传入两个或两个以上参数,要在参数的两侧添加一对小括号,就像这样:
let sum = (num1, num2) => num1 + num2;
// 实际上相当于:
let sum = function(num1, num2) {
return num1 + num2;
};
如果函数没有参数,也要在声明的时候写一组没有内容的小括号,就像这样:
let getName = () => 'Nicholas';
// 实际上相当于:
let getName = function( ) {
return 'Nicholas';
};
为函数编写由多个表达式组成的更传统的函数体,那么需要用花括号包裹函数体,并显示地定义一个返回值,就像这样:
let sum = (num1, num2) => {
return num1 + num2;
}
// 实际上相当于:
let sum = function(num1, num2) {
return num1 + num2;
};
如果想创建一个空函数,需要写一对没有内容的花括号,就像这样:
let doNothing = () => {};
// 实际上相当于:
let doNothing = function( ) {};
如果想让箭头函数向外返回一个对象字面量,则需要将该字面量包裹在小括号里。就像这样:
let getTempItem = id => ({ id: id, name: 'Temp' });
// 实际上相当于:
let getTempItem = function(id) {
return {
id: id,
name: 'Temp'
}
};
创建立即执行函数表达式
只要将箭头函数包裹在小括号里,就可以实现:
let person = ((name) => {
return {
getName: function( ) {
return name;
}
};
})('Nicholas');
console.log(person.getName()); // "Nicholas"
// 实际上相当于:
let person = function(name) {
return {
getName: function( ) {
return name;
}
};
}('Nicholas');
console.log(person.getName()); // "Nicholas"
箭头函数没有 this
函数内的 this
值可以根据函数调用上下文而改变,这有可能错误地影响其他对象。思考一下这个示例:
let PageHandle = {
id: '123456',
init: function( ) {
document.addEventListener('click', function(event) {
this.doSomething(event.type); // 抛出错误
}, false);
},
doSomething: function(type) {
console.log('Handling' + type + 'for' + this.id);
}
}
实际上,因为 this
绑定的是事件目标对象的引用(在这段代码中引用的是document
),而没有绑定 PageHandle
,切由于 this.doSomething()
在目标 document
中不存在,所以无法正常执行。
可以使用 bind()
方法显示地将函数的this绑定到 PageHandle
上来修正这个问题,就像这样:
let PageHandle = {
id: '123456',
init: function( ) {
document.addEventListener('click', (function(event) {
this.doSomething(event.type); // 没有产生错误
}).bind(this), false);
},
doSomething: function(type) {
console.log('Handling' + type + 'for' + this.id);
}
}
箭头函数中没有 this
绑定,必须通过查找作用域链来决定其值。如果箭头函数被箭头函数包含,则 this
绑定的是最近一层非箭头函数的 this
;否则 this
的值会被设置为全局对象。举个例子:
let PageHandle = {
id: '123456',
init: function( ) {
document.addEventListener('click',
event => this.doSomething(event.type), false);
},
doSomething: function(type) {
console.log('Handling' + type + 'for' + this.id);
}
}
箭头函数缺少正常函数所以拥有的 prototype
属性,它的设计初衷是“即用即弃”,所有不能用它定义新的类型。如果尝试通过 new
关键字调用箭头函数,会报错,就像这样:
var MyType = () => {},
object = new MyType(); // 错误,不可以通过 new 关键字抵用箭头函数
箭头函数和数组
举个例子:
var result = value.sort((a, b) => a - b);
// 实际上相当于:
var result = value.sort(function(a, b) {
return a - b;
})
箭头函数没有 arguments 绑定
箭头函数没有自己的 arguments
对象,且无论函数在哪个上下文中执行,箭头函数始终可以访问外围函数的 arguments
对象。举个例子:
function creatArrowFunctonReturnningFirstArg( ) {
return () => arguments[0];
}
var arrowFunction = creatArrowFunctonReturnningFirstArg(5);
console.log(arrowFunction()); // 5