this关键字,是如何把你难倒的?

作为一名实战前端工程师,在jq时代,是经常被this关键字难倒的。几年前每次我意识到程序出现问题的时候,都本能反应是自己的this没有绑定好,于是重新绑定一下,就能解决了。但是他确实一直为难着我。

转眼到了2022年底,我想需要解决一下这个千年难题了。于是我开始认真摸索一番。

到底什么是this

简单说,this就是属性或方法“当前”所在的对象。

为什么这么简单的定义,我们理解不了?

  1. 层层嵌套,改变了this对象
  2. 对象自动携带this,或者全局默认有this对象
  3. 操作dom的时候,this对象变得扑朔迷离。

实际上JavaScript 的变量类型一样,看看这三种类型的变量,是不是更容易理解this了?
局部变量
被捕获变量
全局变量

this的实质

JavaScript 的对象类型存放给变量的是一个引用地址,是一个字符串地址。
this关键字,是如何把你难倒的?_第1张图片

变量o是一个地址(reference)。后面如果要读取o.obj,引擎先从o拿到内存地址,然后再从该地址读出原始的对象,返回它的obj属性。

到这里好像跟this没关系?回忆一下,我们第一次接触this是学什么知识点的时候?没错,构造函数,new一个对象的时候,实例对象默认创建了this变量,这是我们第一次学习到this关键字。

我们把上面的对象o上加入kill方法.

var o = {
	num: 1,
	obj:{a:1},
	kill: function(){
		console.log(this.num)
	}
}

现在问题就来了,调用o.kill()会输出什么?
如果var b = o.kill; b();又输出什么?

答案是o.kill()会输出1;而b()又输出的是undefined。 为什么产生这样的不同呢?

由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。

o.kill()的运行上下文是o这个对象(往上看一下哪个对象引用地址图);而b变量的运行上下文是window全局。b是window对象下的一个变量,所以b是在window对象包裹内部,而window对象其他地方没有定义num变量,所以num就是未定义。

你可能感兴趣的:(JS,前端,javascript,开发语言)