面试题 | this指向
废话不多说!直接看题!
题目描述
1 | var n = 123; |
考察知识点
this指向问题【常考!必考!头疼!】
这里仅对非严格模式下this指向问题进行讨论,严格模式不做讨论
- 一般来说,谁调用this就指向谁
- 在非严格模式下,没有明确的调用者this指向window
- 箭头函数,this指向定义箭头函数的上下文
解析
依次分析结果:
(1)处直接在全局变量window里定义了一个函数,我们知道,对于所有JavaScript全局对象、函数以及用var声明的变量均自动成为window对象的成员,如果直接调用fn(),this指向window(可以理解为是调用了挂载在window上的全局方法fn)
1 | var n = 123; |
(2)处在obj对象上定义了fn1方法,如果通过obj.fn1()调用,this指向调用这个方法的上下文对象,即obj(可以理解为此时fn1是挂载在obj上的)
1 | let obj = { |
(3)处特殊的点在于:在obj对象上定义了fn2方法,但是这个方法里面嵌套的是调用在(1)处定义的fn函数,根据(2)的分析结果,(3-1)处的this指向为obj,但是!这里调用的是fn(),fn()内部的this指向并没有变化【回顾一下,改变this指向的方法是call apply apply】,因此(3-2)处fn的this指向仍为window
1 | let obj = { |
(4)处特殊的点在于:在obj对象上定义了fn3方法,但是这个方法是通过fn赋值得到的,如果你深刻理解函数名是指向函数的指针,就非常容易理解了,fn3处的代码可作改写,更进一步理解!
1 | function fn() { |
(5)处特殊的点在于:fn4是一个箭头函数,箭头函数中的this指向的是定义箭头函数的上下文,箭头函数的作用域在函数fn4内部,fn4所在作用域为最外层的js环境,因为其没有其他函数包裹,最外层的js环境指向的对象是window对象,所以this指向window对象
1 | let obj = { |
(6)处是在全局定义了两个变量bar,基本思路和(4)处有异曲同工之妙,不多说了
1 | var bar = obj.fn1; // ----------------(6) |
拓展
下面打印的结果为:
1 | let n = 123; |
因为,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性,但 let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性