你不知道的Javascript(上卷) | 第六章难点与细节解读(关于this)
2025-05-25 08:02 阅读(36)

写在前面

作为《你不知道的Javascript》忠实读者,多次拜读该著作,本专栏用来分享我对该书的解读,适合希望深入了解这本书的读者阅读

本文可能不会大篇幅去讲解this,只会聚焦于《你不知道的Javascript》第六章(关于this)中不好理解的部分去做解释说明

本文建议在阅读过《你不知道的Javascript》第六章之后再看,这样可以更好了理解我为什么这样写

第六章——关于this

这一章在原文的篇幅比较短,这里我只解决一个问题,而且和this的关系不是很大,如果你是因为看this才点看的这篇文章,已经可以退出这篇文章了,如果你是对《你不知道的Javascript》中第六章有不理解的地方,那这篇文章很适合你

一、我的count到底创建到哪了,创建的是什么

先来看看原文的表述



原文给出了一个失败的计数器,但是这个计数器所蕴含的知识量是巨大的,至少海底火旺是不理解的(一个掘金博主),

我将这里的知识分解为以下的疑问

1.foo.count=0,这行代码发生了什么

原文的表述是向函数对象 foo 添加了一个属性 count,有的人可能会认为这是理所应当的 (海底火旺),但是一个优秀的Javascript学者不会止步于此!

接下来我们讨论,为什么是向foo对象添加了一个属性,而不是一个局部变量?

在讨论这个问题之前,我们要明确一下,属性和局部变量有什么区别?

很多人会说局部变量和属性不是一个东西吗?(海底火旺)

但是事实并非如此,二者的区别还是不小的

众嗦粥汁,在Javascript中,函数也是一种对象,那么我们可以在函数作用域中通过 var let const等方式去声明局部变量,但是如果要添加属性,只能通过foo.a=1等方式

众嗦粥汁,在Javascript中,局部变量的调用并不能使用consle.log(foo.a)的方式访问,但是属性却可以

众嗦粥汁,在Javascript中,foo.a=1声明的属性是静态属性,全局可访问,但是局部变量不可以


以上就是属性和局部变量的区别,那么回到我们刚开始的问题为什么是向foo对象添加了一个属性,而不是一个局部变量?

首先,foo.count的方式无法查找局部变量,也就是无法进行局部变量的LHS查询(但是可以进行属性的LHS查询),就无法默认创建一个局部变量count(但是可以默认创建属性)

再者,Javascript使用词法作用域,无法实现从大气泡到小气泡的变量查询,如果可以动态改变作用域,那不成了动态作用域了?

2.全局作用域中哪来的count?

原文表述是实际上,如果他深入探索的话,就会发现这段代码在无意中创建了一个全局变量 count(原理参见第 2 章),它的值为 NaN。,那么这个全局变量从何而来,看了前文可能读者可能会说,这个全局变量就是foo.count=0创建的静态属性count,它全局可以访问,所以就是它。

大错特错,原文都说了是变量变量,不是属性,再说也没有全局属性这一说,人家叫静态属性

所以全局作用域中哪来的count

这就不得不提到神秘的this了,但这里也只是一提,具体的原理下一篇文章会说,但是现在还没写

this.count++;这里的this指向全局!自然会在全局进行LHS然后查不到,然后创建一个全局变量

那么接下来的问题,为什么值为NAN?

默认创建的全局变量为undefined,undefined++,那就成了NAN

3.那么全局访问count 访问的是全局变量count 还是静态属性 count呢?

全局变量count,静态属性count只能用foo.count来访问,这两个不是一个东西

结语

今天这篇文章也是十分之短,也许明天,我会把this的全解析写出来,也许写不出来。


作者:天天扭码

链接:https://juejin.cn

https://www.zuocode.com