js 中的 this 指向

this 是什么

  1. 在 js 中,this 是一个指针型变量,它动态指向当前函数的运行环境。

  2. 在不同的场景中调用同一个函数,this 的指向也可能会发生变化,但是它永远指向其所在函数的真实调用者;如果没有调用者,就指向全局对象 window。

  3. 在全局作用域下,this 始终指向 window。


普通函数中的 this 指向

普通函数中的 this 的值是在函数被调用时指定的。

全局函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function test() {
console.log(this);
}

test(); // window
window.test(); // window


'use strict'
function test() {
console.log(this);
}

test(); // undefined
window.test(); // window

严格模式下,直接调用 test(),this 指向 undefined。在非严格模式下,直接调用 test(),this 指向 window。

对象中的函数

对象内部方法的 this 指向调用这些方法的对象,也就是谁调用就指向谁

1
2
3
4
5
6
7
8
9
const obj = {
name: "Silence",
f() {
console.log(this.name);
}
}


obj.f(); // Silence

因为是 obj 调用的 f 方法,所以 f 中的 this 就指向 obj。

1
2
3
4
5
6
7
8
9
10
11
const obj = {
name: "Silence",
f() {
return function () {
console.log(this.name);
}
}
}


obj.f()(); // undefined

实际上 this 指向 window。因为 obj.f()() 相当于:

1
2
const x = f();
x();

可以看出,x 方法是被 window 调用的,因此 this 指向 window。


箭头函数中的 this

箭头函数中没有 this 和 arguments。箭头函数没有自己的 this 指向,它会捕获自己定义所处的外层执行环境,并且继承这个 this 值,指向当前定义时所在的对象

箭头函数中的 this 值在被定义的时候就已经确定了,之后永远都不会改变。即使使用 call()、applay()、bind() 方法也改变不了。

1
2
3
4
5
6
7
8
9
const obj = {
name: "Silence",
f: () => {
console.log(this.name);
}
}


obj.f(); // Silence
1
2
3
4
5
6
7
8
9
10
11
const obj = {
name: "Silence",
f() {
return () => {
console.log(this.name);
}
}
}


obj.f()(); // Silence

由于箭头函数中没有 this 指向,它又被定义在函数 f 中,因此,它就继承函数 f 的 this 指向,即指向 obj。