前言
本文将从以下几方面阐述 Javascript 中 this 的指向问题。
- 标准函数中,
this
的引用值是什么 - 箭头函数中,
this
的引用值是什么 - 使用
new
关键字创建对象时,this
的引用值是什么 - 闭包中使用
this
时,this
的引用值什么
标准函数中,this 的引用值是什么
标准函数中,this引用的是把函数当成方法调用的上下文对象
在标准函数中this
的值是会根据方法被调用的情况改变所引用的值
1 | window.identity = "The Window" |
箭头函数中,this 的引用值是什么
在箭头函数中,this引用的是定义箭头函数的上下文
由此可以看出箭头函数中的this
引用值是固定的
1 | window.identity = "The Window" |
面试的时候我就遇到了这个问题,当时我心想
“在箭头函数中,this引用的是定义箭头函数的上下文对象”
大家如果仔细比较这两句话可以发现我心里想的多了两个字(或者说我就是囫囵的看了一遍书,根本没有好好的去理解、去验证),这两个字不多不少让我把this
的引用值认为成object
这个对象了,所以我认为最后的结果应该是My Object
。
那么我们现在来具体的看看这个定义箭头函数的上下文是什么呢?
在我看来,我们可以把this值看成上下文
那定义箭头函数的上下文其实就是object
的this
值呗;那我们要知道的其实就是object
的this
的identity
属性是什么呗?
在上方代码的倒数第二行就是为了说明这个问题,由于属性testIdentity
的值是The Window
我们能得出object
的this
引用值其实是window
;
由于函数getIdentityFunc
中的this
引用值其实是object
的this
,也就是window
。所以函数getIdentityFunc
中的this.identity
是The Window
。
既然箭头函数中的 this 是固定的,那么类似 call 的函数能改变 this 的引用值吗
在JS中我们可以使用call
、apply
、bind
方法改变this
指向,既然箭头函数的this
值引用值是固定的,那我们能使用这几个方法改变这个引用值吗?
看下面的代码
1 | window.identity = "The Window" |
1 | window.identity = "The Window" |
对比这两处代码我们能发现call方法根本无法改变箭头函数的this
的引用值。
使用 new 关键字创建对象时,this 的引用值是什么
在实例中this的引用值是当前所在的实例
1 | window.identity = "The Window" |
我们可以看到两个函数中输出的都是My Object
,getIdentityFunc
函数的结果也之前调用的差别不大,因为在这个函数里面this
的引用值依然是obj
这个上下文对象。
但是在函数getIdentityFunc1
中,虽然都是箭头函数(和第二个例子的代码做比较),但是这一次的结果确实My Object
,也就是说这一次的this
引用值是对象obj
。
那么这个情况的原因是什么呢?我们来回忆一下刚刚第二个例子里面箭头函数的this
值是等于对象object
的this
值,事实上这一次也是。所以造成这两次结果不同的原因其实是这两次的“函数上下文”不一样了。
- 第二个例子中
object
的函数上下文this
引用值是window
- 这次
obj
的函数上下文this
的引用值是他自己obj
闭包中使用 this 时,this 的引用值什么
在闭包中使用 this 会让代码变复杂。如果内部函数没有使用箭头函数定义,则 this 对象会在运行时绑定到执行函数的上下文。如果在全局函数中调用,则 this 在非严格模式下等于 window,在严格模式下等于 undefined。如果作为某个对象的方法调用,则 this 等于这个对象。
从这一段话中我们可以提取出以下几条信息。
- 如果闭包的内部函数是使用箭头函数定义的,基本不受影响,我们只需要按照箭头函数的
this
指向判断方法判断就可以。 - 如果在全局函数中调用,则 this 在非严格模式下等于 window,在严格模式下等于 undefined
- 如果作为某个对象的方法调用,则 this 等于这个对象
内部函数使用箭头函数定义的,基本不受影响
1 | window.identity = "The Window" |
如果在全局函数中调用,则 this 在非严格模式下等于 window,在严格模式下等于 undefined
1 | window.identity = "The Window" |
如果作为某个对象的方法调用,则 this 等于这个对象
1 | window.identity = "The Window" |
练习题目
1 | const test = { |
1 | var name = "window" |
1 | var name = "window" |
1 | window.identity = "The Window" |
文章参考文献
- 《JavaScript 高级程序设计》
- JavaScript之彻底搞懂this的指向