ES6允许使用箭头(=>)定义函数,箭头函数的语法多变,根据实际的使用场景有多种形式,但需要由函数参数、箭头和函数体组成。
- 箭头函数的语法
单一参数、函数体只有一条语句的箭头函数:
let title = msg => msg
// 相当于
function title(msg) {
return msg
}
函数有多个的参数,需要在参数的两侧添加一对圆括号:
let title = (msg, name) => `${name},${title}`
// 相当于
function title(msg, name) {
return `${name},${title}`
}
如果函数没有参数,需要使用一对空的圆括号:
let title = () => "welcome you"
函数体有多条语句,用花括号包裹函数体:
let title = (msg, title) => {
let cont = msg + title
return cont
}
箭头函数的返回值是一个对象字面量,需要将该对象字面量包裹在圆括号中:
let title = (msg, name) => ({msg: msg, name: name})
// 相当于
function title(msg, name) {
return {
msg: msg,
name: name
}
}
- 箭头函数和this
JavaScript中的this关键字并不是指向对象本身,其指向是可以改变的,根据当前执行上下文的变化而变化。
var title = 'welcome'
function sayHello(name) {
console.log(`${this.title},name`)
}
var obj = {
title: 'Hello',
sayHello: sayHello
}
sayHello('zhangsan') // welcome,zhangsan
obj.sayHello('liwu') // Hello,liwu
var sayHi = obj.sayHello()
sayHi('wangliu') // welcome wangliu
分析上面地js代码:
调用sayHello('zhangsan')时,相当于执行window.sayHello('zhangsan'),因此函数内部的this指向的时window对象,最后输出“welcome,zhangsan”
调用obj.sayHello('liwu')时,函数内部的this指向的是obj对象,而obj对象内部定义了title属性,最后输出“Hello,liwu”
调用sayHi('wangliu')时,虽然该函数是由obj.sayHello赋值得到,但在执行sayHi()函数时,当前的执行上下文对象时window对象,相当于调用window.sayHi('wangliu'),因此最后输出“welcome wanliu”
为了解决this指向问题,可以使用函数对象的bind()方法,将this明确地绑定到某个对象。
var obj = {
title: 'Hello',
sayHello: sayHello
}
obj.sayHello('liwu').bind(obj) // Hello,liwu
使用bind()方法实际上是创建了一个新地函数,称为绑定函数,该函数的this被绑定到参数传入的对象。
也可以使用箭头函数来解决this问题。箭头函数中没有this绑定,必须通过查找作用域决定其值。如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值会被设置为全局对象。
var obj = {
title: 'Hello',
sayHello: function() {
setTimeout(() => console.log(`this.title`), 2000)
}
}
obj.sayHello() // Hello
使用箭头函数需注意几点:
(1)没有this、super、arguments、new.target绑定,箭头函数中的this、super、arguments、new.target这些值由外围最近一层非箭头函数决定。
(2)不能通过new关键字调用。箭头函数不能被用作构造函数,也就是不可以使用new关键字调用箭头函数,否则程序会抛出错误
(3)没有原型。因为不可通过new关键字调用箭头函数,所以没有构建原型的需求,就不存在prototype这属性
(4)不支持arguments对象。箭头函数没有arguments绑定,只能通过命名参数和rest参数这两形式访问函数的参数
网友评论