1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > javascript中的this指向问题

javascript中的this指向问题

时间:2020-10-31 01:03:37

相关推荐

javascript中的this指向问题

很多学java的同学在接触js之后使用this的时候都是懵逼的,这特么怎么回事,怎么老是给我报“Cannot read property 'xxx' of undefined”,我的this.xxx.xxx明明已经有值啊,为什么会出现这种情况。

面对上面的问题,很多js的初学者都会很懵,不知道js的this为什么就不指向自己想要的那个this了。

我以前也遇见过这种疑惑,直到我后来学习了一个大佬的博客(至于是谁的我还真忘了),我彻底弄懂了js的this为什么这么调皮了。

在js中,函数的调用有三种方式:

1. 直接调用:例如a(...params)

2. 对象调用:例如obj.a(...params)

3. new 函数调用:例如new A(...params)

但其实这些都是语法糖。

直接调用其实写完整就是:

a.call(undefined,...params)

对象调用写完整是:

obj.a.call(obj,...params)

而使用 new 调用函数的时候,例如

var a = new A(...params)

其实写完整是:

var a = {}a.call(a, ...params)a.__proto__ = A.prototype

这就是this为什么会乱跳的根本原因所在。

在js中,根据函数的调用方式不同,this的指向变化也不同:

1.直接调用函数,this指向全局:

这里会因为环境不同而产生不同的结果:

在严格模式下,this是undefined,但是我们大部分代码都是在非严格模式下写的,所以不探讨这个情况。

在非严格模式下,浏览器环境下this会指向window,node环境中会指向global。

以浏览器代码为例:

function a(){console.log(this)}a()

显示结果是:

这里出现的问题是最多的,因为很多时候函数都是直接调用的,所以this会直接指向window,导致取值错误。

2.对象调用函数,this指向调用对象:

先看代码:

const obj = {a:1,b: function (){console.log(this.a)}}

obj.b()

这个打印出来结果是1,毋庸置疑。因为这个this指向调用对象obj,所以this.a就是obj.a。

再看一个代码:

const obj = {a:1,b:{a:2,b:function (){console.log(this.a)}} }obj.b.b()

这里打印的是多少呢。把代码在浏览器中运行一下:

是2,因为obj.b.b()就相当于obj.b.b.call(obj.b),所以this指向obj.b,那么打印出来的自然是obj.b.a。

再看一段代码:

var a = 'This is brower'

const obj = {a:1,b:function(){console.log(this.a)}}const fn = obj.bfn()

这里打印的是多少呢。把代码在浏览器中运行一下:

这是为什么?

这是因为fn = obj.b = function(){...},在这里的fn被赋值function(){...},跟obj.b没有关系了,所以直接调用fn其中的this指向window,而window.a则是 'This is brower'。

3.使用构造函数调用,this 指向创建的对象:

照例,先看代码:

function A(){this.a = 1this.b = 2 }var a = new A()console.log(a.a)console.log(a.b)

这里打印出来的自然是1和2,因为new A()过程中将this指向了a。

但是在这里有个坑,就是构造函数的返回值如果是引用类型的值就会引发错误,会直接将this指向返回的对象。

function A(){this.a = 1return {a:2} }var a = new A()console.log(a.a)

在浏览器中运行查看结果:

上图中可以看出,a指向的是A返回的对象,所以a.a打印出的是2。

返回的如果是一个数组的话,a也会指向返回的数组,a.a就会打印出 undefined。

在es6中出现了箭头函数,箭头函数中的this始终指向函数所处的块级作用域的this。

看代码:

var a = 'This is window'

const obj = {a: 1,b: () => {console.log(this.a)}}obj.b()

上答案:

是不是又懵了,明明是obj调用的,但是this却指向了window。

这就是箭头函数的优点,因为它的this指向是固定的,永远指向所处的块级作用域内部的this。

在这里obj.b所处的块级作用域就是全局,所以其中的this指向window。

再来一段代码:

function a(){this.a = 10return {a:1,b:()=>{console.log(this.a)}} } const obj = a()obj.b()

继续直接上答案:

这次差不多懂了吧,这个箭头函数创建的时候是处于方法 a 的作用域内部的,所以箭头函数内部的this始终指向方法 a 中的this。

上述就是我在学习js中的this时遇到的所有关于this的调用的问题,估计应该可能大概差不多maybe是有没有涉及到的,但是关于this的这些差不多够了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。