今天来看一下箭头函数中this的指向问题,面试问到最多的问题之一,也是经常搞混的一个问题,今天这里特意记录下来,好废话不多说开整。
经典问答环节:
面试官:你知道箭头函数和普通函数的区别是什么吗?
你:他们之间this指向不同,普通函数this指向调用他的实例对象,箭头函数this指向他的执行上下文。
面试官:能详细说一下吗?
你:。。。。。。
箭头函数的this指向规则
- 箭头函数没有prototype,所以箭头函数本身没有this
let a = () => {}
console.log(a.prototype) // undefined
- 箭头函数的this指向它的执行上下文
箭头函数不会创建自己的this,所以他没有自己的this,他只会从自己作用域链的上一层继承this,在箭头函数定义时他会捕获自己所处的执行上下文环境的this并继承下来,所以箭头函数的this是在他被定义的时候就已经确定了,之后不会再改变了。
这里不得不提一下执行上下文的概念。
执行上下文:指当前执行环境中的变量、函数声明,参数(arguments),作用域链,this等信息。分为全局执行上下文、函数执行上下文,其区别在于全局执行上下文只有一个,函数执行上下文在每次调用函数时候会创建一个新的函数执行上下文。
- 全局执行上下文 在浏览器中全局上下文的变量对象就是window对象
// 在浏览器控制台直接console this
console.log(this)
// window对象
- 函数指向上下文 函数指向上下文可存在无数个,没但一个函数被调用时都会创建一个函数指向上下文,并且,同一个函数被多次调用时,都会创建一个新的上下文环境。
PS:多个执行上下文调用顺序是什么,怎么管理,这就提到了执行上下文栈,也叫执行栈,留到以后说。
这里回到箭头函数的this指向问题
const obj = {
a: 1,
b: () => {
console.log(this.a)
}
}
obj.b() // undefined
这里的解释是obj对象没有执行上下文环境,所以向上查找到全局执行上下文环境,即window,window.a为undefined
const obj1 = {
a: 1,
b: function () {
return () => {
console.log(this.a)
}
}
}
obj1.b()() // 1
这里就是箭头处于了一个函数执行上下文环境b,而b的this指向obj1,所以这里打印出来是个1
这样就应该比较清晰了
箭头函数向上找函数的指向
普通函数向上找对象的指向。