前言
不知道大家在前端面试过程中,有没有被面试官问过关于this
指向哪里,怎么改变this
指向的问题,这个问题即使工作了多年的小伙伴也会一知半解,因此这篇文章详细分析了this
指向的问题,让深入理解this
指向。
大纲
什么是this
函数在调用时会创建一个执行环境,
this
是在运行时基于函数的执行环境绑定的,它可以允许函数内部引用上下文中的执行变量,使函数编程更为优雅简洁。
来看看下面这段代码,为什么不同的调用方法打印出来的结果会不一样呢?
var a = 10
const obj = {
a: 20,
foo: function() {
console.log(this.a)
return function() {
console.log(this.a)
}
}
}
obj.foo()() // 20 10
const fn = obj.foo
fn() // 10
其实很简单,因为这里不同调用方式的this
指向不同。为什么不同的函数调用方式this
就指向不同?这是由什么决定的呢?下面让我们带着疑问开始深入理解this
问题吧!
this的绑定规则
默认绑定
默认绑定规则下,函数的运行环境为全局环境,this
默认指向Window
。
默认绑定规则下的情况有以下几种
- 全局函数
this
指向Window
- 独立函数调用
this
指向Window
- 自执行函数调用
this
指向Window
- 闭包内部
this
指向window
全局函数this指向Window
当在全局函数内直接打印this
,可以看到this
指向为Window
。
独立函数调用,this指向Window
独立函数调用,即直接调用函数,如foo()
,
function foo() {
console.log(this);
}
foo()
这里的foo
被默认挂在到Window
上,相当于window.foo()
,根据函数隐式绑定规则,谁调用就指向谁,这里指向的this
指向Window
,结果如下:
同理,如果在一个嵌套函数中直接调用的函数,也属于独立函数调用,此时this
也指向Window
:
var a = 10
var obj = {
a: 20,
foo: function() {
console.log(this); // {a: 20, foo: ƒ}
console.log(this.a); // 20
function son() {
console.log(this); // Window
console.log(this.a); // 10
}
// 独立函数调用
son()
}
}
obj.foo()
上面代码中,对象obj
中的方法foo
内部还嵌套了一个子函数son
,当直接调用son
方法时,son
内部的this
指向Window
,因此son
内部的this.a
结果为全局的变量a,即10。
那么当在son
函数内部想要使用到obj
中的变量a
怎么办呢?很简单,直接把this
对象赋值给另一个变量that
,在son
方法内部引用此变量即可:
var a = 10
var obj = {
a: 20,
foo: function() {
const that = this
function son() {