箭头函数是es6
的新增的定义函数表达式的方法,它比以前的函数表达式更为的简洁,同时这种方式也有特别的地方
语法
完整写法
( /* 参数 */ ) => { /* 函数体 */ }
简写
- 当参数只有一个时:可以省略
()
- 没有参数时:不能省
- 当函数体只有一个表达式时:可以省略
{}
- 当 表达式是一个对象时需要用
()
包裹 - 该表达式的结果会作为这个箭头函数的返回值
- 当 表达式是一个对象时需要用
// 简短式1
param => {
console.log(param)
}
// 简短式2
const add = (num1, num2) => num1 + num2
console.log(add(1, 2)) // 3
// 返回值是对象时
const fn = () => { name: "fn" } // 错误
const fn = () => ({ name: "fn" }) // 正确
特点
- 没有自己的
this
arguments
super
以及new.target
- 不能作为构造函数
引入箭头函数除了语法更为简洁之外,更重要的是箭头函数中的this
指向。
在之前以及复习了普通函数的this
是如何指向的,而在箭头函数中,它不会绑定自己的this
,它只会从自己的作用域链的上一层继承 this
// 定义函数如下
function fn() {
console.log("this1: ", this)
setTimeout(() => { // 此处使用箭头函数
console.log("this2: ",this)
})
}
// 通过两种方式调用 fn
fn() // this1: 全局对象 this2: 全局对象
const obj = {
name: "obj",
fn,
}
obj.fn() // this1: obj this2: obj
由结果可以看出:无论在什么时候,箭头函数中的
this
都与上层作用域的this
保持一致,原因就是因为箭头函数用的this
就是父作用域的this
如果将箭头函数换成普通函数
// 定义函数如下
function fn() {
console.log("this1: ", this)
setTimeout(() => { // 此处使用箭头函数
console.log("this2: ",this)
})
}
// 通过两种方式调用 fn
fn() // this1: 全局对象 this2: 全局对象
const obj = {
name: "obj",
fn,
}
obj.fn() // this1: obj this2: 全局对象
此时无论怎样调用,setTimeout 回调中的this都是指向全局的
由于箭头函数没有自己的
this
,所以 之前的this
绑定规则都没有用,call apply bind
等函数对于箭头函数也不好使
测试
- 在同一个对象中分别使用箭头函数与普通函数
const obj = {
name: "obj",
fn1: () => {
console.log(this)
},
fn2: function () {
console.log(this)
},
}
obj.fn1() // 全局
obj.fn2() // obj
这是因为对象不会创建作用域,所以fn1中的this是obj所在作用域的this,而fn2遵循普通函数的规则
- 回调中的箭头函数与普通函数
function fn() {
console.log(this)
setTimeout(() => {
console.log(this)
})
setTimeout(function () {
console.log(this)
})
}
虽然这里调用完了都是指向的全局,但是开启严格模式之后前两个this是
undefined
最后一个是全局,这应该也可以看出来两者差别
结束语
反正箭头函数中使用的this
就与声明时的位置有关系,至于arguments
可以通过es6
的剩余参数实现