ES6:JavaScript箭头函数的this指向与穿透问题

以一个例子引出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const person ={
name: "郭德纲",
hobbies:["写代码","说相声","烫头"],
printHobbies:function(){
this.hobbies.map(function(res){
console.log(this.name+"喜欢"+res)
})
}
}
person.printHobbies()
//输出: 喜欢写代码
喜欢说相声
喜欢烫头
</script>

打印中“郭德纲”没有出现,原因出在function(res){console.log(this.name+"喜欢"+res)}这个回调函数上,这个匿名的回调函数没有绑定调用者(ES5中函数内this指向调用者),其内部的this无从指向,只能遵循匿名函数this指向windows这个规则去指向windows,而windows的name=’’

1、ES5解决回调函数this指向的方法:用that=this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
const person ={
name: "郭德纲",
hobbies:["写代码","说相声","烫头"],
printHobbies:function(){
var that = this
this.hobbies.map(function(res){
console.log(that.name+"喜欢"+res)
})
}
}
person.printHobbies()
//输出: 郭德纲喜欢写代码
郭德纲喜欢说相声
郭德纲喜欢烫头
</script>

此方法在回调函数以外将指向对象的this存在that中,再通过that.name调用对象的name

2、JavaScript箭头函数的this指向与穿透

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
const person ={
name: "郭德纲",
hobbies:["写代码","说相声","烫头"],
printHobbies:function(){
this.hobbies.map((res) => {
console.log(this.name+"喜欢"+res)
})
}
}
person.printHobbies()
//输出: 郭德纲喜欢写代码
郭德纲喜欢说相声
郭德纲喜欢烫头
</script>

由于箭头函数的this指向是词法作用域,可以穿透至它的父级作用域,所以它的this指向和父级作用域的this指向一样

词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用
词法作用域是在写代码或者定义时确定的,而动态作用域是在运行时确定的(this也是!)

3、箭头函数不适用的场景

1、构造函数不能使用箭头函数,因为构造函数需要绑定到对象身上
2、需要绑定到当前对象触发dom事件的时候
3、需要使用arguments,arguments可以接收函数的参数,箭头函数内没有arguments这个类数组的,需要再最外加一个(…arg)

1
2
3
4
5
6
<script>
const sum =(...arg)=>{
return arg.reduce((preSum,val)=>
preSum + val,0)
}
</script>

ES6:JavaScript箭头函数的this指向与穿透问题
https://wwwhisperr.github.io/2022/10/01/page/
作者
Whisper
发布于
2022年10月1日
许可协议