this.this? 又在模板里面写this。。。。。

1,029 阅读3分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

不知道小伙伴们有没有这样的疑问。this是个关键字? this.this为什么不指向自己?

答: this 的确是个关键字,不是什么全局对象,也不是内置属性,只不过一般会指向某个对象。

然后,this.this === undefined。

image.png

this.this

一般人肯定也不会这样想,也就更不会这样写了。

一开始我也没有这么想过。 直到某天,有个小伙伴甲在群里问,他的vue语法有没有什么问题,怎么不起作用,还说了他的期望云云。我一眼就看到了 类似这样的写法<p>{{this.msg}}</p> ,先不管,他其他有啥错。就这个,我就立马指出来了, 甲,你怎么又在模板里写this,上次不是跟你说过了吗?.....

但是甲毫无知觉地问道,这样有啥问题吗? 我心想,是时候让你知道vue的模板语法是要经过编译的, 所有绑定语法和小胡子语法,里面写的标识符都会去当前组件的对应属性方法上找。 这也是为啥不能在模板里使用 Date Math ParseInt等一些全局对象和方法.

但是我表达能力有限,甲似乎并不明白, 我就直接说,你在img的src上绑定一个路径url ,被编译之后就是this.url ,但是你写的是this.url,那么编译后,就是this.this.url.

甲恍然大悟,并发誓下次一定注意。 呵呵,还有下次?

不过我也有点好奇,于是打印了一下 this.this . 结果自然是 undefined

作用域链 和 原型链

作用域链,当前词法环境闭包里面没有,就会去外面找。那么为啥this.this 是undefined,为啥不能在模板写全局方法和属性,不能顺着作用域链往外找到吗?

当然不能,作用域链的查找机制,是用来查找标识符,限于表层的。

比如 要访问 a.b,首先会在当前作用域查找 a 这个变量,没有就往外继续, 直到找到为止。

作用域链查找完毕,原型链差不多该登场了。假设a找到了, 要访问a.b,也就是要访问a上面的b属性。如果实例a上面没有这个属性b,那么就会去a的原型上找a.__proto__.b, 如果没有继续往源头找·······

如此一来,我们想访问this.this的时候,首先找到this,这个就不多说了,构造函数指向实例,函数内部,谁调用就指向谁,还有call apply bind, 没有明确指向就是全局globalThis. (以上所说在非严格模式下适用)

根据上述规则就找到了this,然后就是找this实例上的this属性,如果当前上下文上没有这个属性,那么去它的原型上找······ 但是, 经过了一阵查找,在Object.prototype上也没有找到,查无此属性,于是返回undefined。

this.this 第一个this是关键字,第二个就是一个属性名,可不是什么关键字了。

最后

访问一个变量,首先是找到一级的标识符,通过作用域链来查找,找到a.b的a ,

如果是要访问它下面的属性,那么接下来,原型链就登场了。

注意到开头的图片了吗。虽然this.this不会循环,但是window.window 会。

我也有点费解,如果有知道的小伙伴,还望不吝赐教。