简述JS中THIS的指向?

这里是修真院前端小课堂,每篇分享文从

八个方面深度解析前端知识/技能,本篇分享的是:

【简述JS中THIS的指向?】

大家好,我是IT修真院武汉分院web第16期的学员孟晨,一枚正直纯洁善良的web程序员 今天给大家分享一下,修真院官网js(职业)任务四,深度思考中的知识点——简述JS中THIS的指向?

1.背景介绍
this是什么?它有着什么样的功能?
this是Javascript语言的一个关键字。 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。 随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。

this的特性:
this的指向在函数创建的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

2.知识剖析
下面会用一系列的代码片段来详细解读this

  1. 作为普通函数在全局环境中被调用

在全局环境里面,this 永远指向 window,因此在全局环境里作为普通函数被调用的时候,this 也是指向 window。

这里调用了a函数,而a函数的执行环境是全局环境,这里的this也就指向了全局变量window。

在全局环境里面,this 永远指向 window,因此在全局环境里作为普通函数被调用的时候,this 也是指向 window。

2.作为对象的属性被调用

先来个总结:如果函数作为一个对象的属性方法,并且被调用的时候,那么这个属性方法中的this 就指向这个对象,来看代码:

这里出现的结果与上面相同,因为this指向它的直接上级

稍微复杂一点的情况

这里同样也是对象o点出来的,但是同样this并没有执行它

通过以上例子可以有一下结论

情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window

情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象

情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

但是还有一个特殊的例子

?这里this指向的还是window

想要明白为什么还需要理解一句话

即this永远指向的是最后调用它的对象

也就是看它执行的时候是谁调用的,虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和之前例子是不一样的,之前是直接执行了fn。

3.作为构造函数被调用

作为构造函数被调用的时候,this 代表它即将 new 出来的对象;

如果不加 new,表示即作为普通函数调用,指向 window。

如果不加 new,表示即作为普通函数调用,指向 window。

4.作为 CALL/APPLY/BIND 方法的调用

作为 call/apply/bind 方法被调用的时候指向传入的值。

5.绑定事件,事件触发后的THIS

元素绑定事件,事件触发后,执行的函数中的this 指向的是当前元素(标签)

3.常见问题
THIS遇到RETURN怎么办?

如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

虽然null,undefind也是对象,但是在这里this还是指向那个函数的实例,因为null,undefind比较特殊。

可以看看例子

再来2个

然后有个较为特殊的就是null虽然也是对象,但表现出来的是这样的

5.代码实战
6.拓展思考
如何改变this的指向?

setTimeout、setInterval中的this是指向哪里?

如何改变this的指向?

可以使用call或者apply的方法改变指向

如果xxxx.call(a),this就指向a;当a为null或者undefined的时候,会指向window; 假如说要传参,构造函数名.call(“a”,“b”,“c”),它的第一个参数传到的是this;apply类似,但是与之不同的是,要书写成: 构造函数名.apply(“a”,[“b”,“c”])的形式,这就是差别;

可以看一看例子

setTimeout、setInterval中的this是指向哪里?

《 javascript 高级程序设计》中写到:“超时调用的代码都是在全局执行域中执行的”。setTimeout/setInterval 执行的时候,this 默认指向 window 对象,除非手动改变 this 的指向。

还是看一看例子

之前说过,如果直接执行回调函数而没有绑定作用域,那么它的’this’是指向全局对象(‘window’),在严格模式下会指向’undefined’,然而在’setTimeout’中的回调函数在严格模式下却表现出不同

看看例子

按理说我们加了严格模式,foo 调用也没有指定’this’,应该是出来 ‘undefined’,但是这里仍然出现了全局对象,难道是严格模式失效了吗?
并不,即使在严格模式下,‘setTimeout’ 方法在调用传入函数的时候,如果这个函数没有指定了的 ‘this’,那么它会做一个隐式的操作----自动地注入全局上下文,等同于调用’foo.apply(window)'而非 ‘foo()’;
当然,如果我们在传入函数的时候已经指定 ‘this’,那么就不会被注入全局对象,比如: ‘setTimeout(foo.bind(obj), 1);’;

7.参考文献
JavaScript中的this
彻底理解js中this的指向,不必硬背。

8.更多讨论

这里是技能树·IT修真院:https://www.jnshu.com,初学者转行到互联网的聚集地

你可能感兴趣的:(从零开始学前端)