
彻底搞懂 JavaScript 中的 this 指向
前言
本文将从以下几方面阐述 Javascript 中 this 的指向问题。
- 标准函数中,this的引用值是什么
- 箭头函数中,this的引用值是什么
- 使用new关键字创建对象时,this的引用值是什么
- 闭包中使用this时,this的引用值什么
标准函数中,this 的引用值是什么
标准函数中,this引用的是把函数当成方法调用的上下文对象
在标准函数中this的值是会根据方法被调用的情况改变所引用的值
箭头函数中,this 的引用值是什么
在箭头函数中,this引用的是定义箭头函数的上下文
由此可以看出箭头函数中的this引用值是固定的
面试的时候我就遇到了这个问题,当时我心想
“在箭头函数中,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值引用值是固定的,那我们能使用这几个方法改变这个引用值吗?
看下面的代码
对比这两处代码我们能发现call方法根本无法改变箭头函数的this的引用值。
使用 new 关键字创建对象时,this 的引用值是什么
在实例中this的引用值是当前所在的实例
我们可以看到两个函数中输出的都是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 等于这个对象
内部函数使用箭头函数定义的,基本不受影响
如果在全局函数中调用,则 this 在非严格模式下等于 window,在严格模式下等于 undefined
如果作为某个对象的方法调用,则 this 等于这个对象
练习题目
