前言

this 的指向问题在 JavaScript 中对初学者来说一直就像一个谜一样。

在其他面向对象语言中,this 关键字只有在对象调用自身的属性或者方法时才会出现,此时 this 就是指向调用者的一个指针,这很符合直觉,但在 JavaScript 中就复杂很多。

在我看来,JavaScript 中的 this 分为两大类:

  1. 作为函数调用,指向宿主环境的全局对象
  2. 当作方法调用,this 指向调用它的对象

1. 作为函数调用时

宿主环境就是指代码的执行环境,服务器端就是 Node,前端就是浏览器,以下代码都在浏览器中执行:

1
2
3
4
function sayThis() {
console.log(this === window)
}
sayThis() // true

一个普通函数的定义以及调用,this 指向 window

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
window.val = 'window'

const obj = {
val: 'obj',
sayVal: function() {
function _sayVal() {
console.log(this.val)
}
_sayVal()
console.log(this.val)
},
}

obj.sayVal()
// window
// obj

_sayThis 是定义在方法中的普通函数,函数体中 this 的指向还是 window

我们换一种方式理解这种现象,window 本身就是一个对象,所有的全局变量都是 window 的一个属性或者方法,假如把普通函数看做 window 对象的一个方法,是不是就可以理解此时 this 的指向了?

注意:在严格模式下,这种情况下的 this 是 undefined

2. 当作方法调用

在这种情况中,当分不清 this 的指向问题时,我认为关键在于没正确地辨别方法执行时谁是调用方。