简单理解JS中的this关键字
本文最后更新于:2023年3月21日 下午
背景
之前在看《You Don’t Know JS - 1st Edition》这本书的时候,它对this的解释是针对各个this在哪里被调用分为四种情况。
- 默认绑定 (独立函数调用)
- 隐式绑定 (作为方法调用)
- 显示绑定 (call、this、bind)
- new绑定 (构造函数中的this)
书中分别解释了在四种情况中this的值应该是什么。我也记住了,但是总感觉缺少某根线,把这四种情况串联起来。
这几天在看 《JavaScript: The Definitive Guide, Seventh Edition》 这本书,我直接看的英文版,我看到目前的评价是,不愧是权威指南,整本书都非常通俗易懂,看英文版完全没有任何障碍。
权威指南中对this的解释提出了那根线,把this在不同情况下都串联起来的线。
函数体中的this 指向 函数作为方法被调用时所在的那个对象。
解释
作为方法调用
这是最清晰的一种情形。
1 |
|
这里的函数f是作为对象o的一个方法被调用的,所以this指向对象o
《You Don’t Know JS》中的隐式绑定就属于这种最简单和清晰的情况。
独立函数调用
这种情况对应《You Don’t Know JS》中默认绑定。
1 |
|
函数单独调用,这时this会指向全局对象。你可以这样想,这时f就像全局对象的一个方法,直接调用这个函数,可以看作调用了全局对象globalThis的方法f,所以this指向globalThis。
这样想是有一定道理的,在浏览器环境下,f确实会成为全局对象的一个方法。
1 |
|
但是这样想不太准确,在node环境下函数f根本不是全局对象的一个方法。
1 |
|
是不是感觉乱乱的?还好在严格模式下,这种独立函数调用的情况,this将直接指向undefined。
1 |
|
这实际上也很好理解,因为形式上f调用时没有作为任何对象的方法,所以undefined是合理的。
显示绑定
利用call、apply、bind修改this的指向。
1 |
|
我们单独拿出f.call(o)
这条语句来看,它看起来是不是就是在说,把函数f在对象o上运行?所以显示绑定在某种程度上也可以看作暂时把函数f当作了对象o的方法,然后调用。
构造函数中的this
这对应《You Don’t Know JS》中 new绑定。
1 |
|
在这里,定义了一个构造函数F,然后利用new关键字调用了这个构造函数F,生成了一个对象f。
我们知道,构造函数中的this实际上就是f,即新生成的对象。
所以这可以怎么看呢?调用new调用构造函数时,JS会先生成一个空对象,然后把构造函数F作为这个空对象的方法去调用,这时this就是空对象了,之后构造函数的语句依次被调用,这个对象初始化完毕后自动返回,就是f了。
总结
利用这跟线 函数体中的this 指向 函数作为方法被调用时所在的那个对象 虽然有些不合理,但是确实能够较好的"解释"和记住this在各种情况下的情况。