宝哥软件园

Javascript变量范围和范围链的详细说明

编辑:宝哥软件园 来源:互联网 时间:2021-09-09

工作了几年,js学得不是很好。正好周末有一些空余时间,就干脆买了这本《js权威指南》,著名的犀牛书,彻底读js。买这本书的第一印象是贼厚,但后半部分是参考手册。

1.范围

说到变量,首先要讲的肯定是范围。仅仅因为你不熟悉js的范围,你就会经常把面向对象的范围放在地图上。毕竟有些东西总是习惯的,但是不可能每次都复制。然后下一个问题来了。JS是什么范围,当然是功能范围。我们的浏览器是一个实例化的窗口对象。如果在窗口下定义了名称字段,则该名称字段具有窗口的功能范围,即可以在窗口下访问。例如,如果在窗口下定义了一个函数ctrl IP,然后在其中定义了一个名称,则新定义的名称只能在ctrl IP函数下使用,而旧名称继续在窗口下使用。

从图中可以看出两点:

1:在window下定义了一个名字,甚至可以在function下定义同名的名字,这在C#中是无法想象的。

2.JS下可以瞎。它只识别自己的范围,所以第一个‘秒’出现了。你可能认为这没有什么不寻常的。这是因为你可能并不真正理解什么是功能范围。解析器执行携程时,首先要找到携程下的所有局部变量,然后执行后续语句。既然是先找,那么var name='second '

可以看到,在ctrip函数下,第一个console.log输出是未定义的。这个结果可以确认已经做的第一件事是收集局部变量名。有人可能会说为什么它没有成为“第二”。那是因为初始化操作必须一句一句的执行,所以当在ctrip函数中执行console.log(name)时,解析器只知道有一个未赋值的变量名,所以说到console,

二:范围链

从上面的例子中,我们也清楚地知道,函数中定义的变量只在函数范围内有作用域。同时,我们也看到上面的例子只是一层嵌套。window是一个大函数,里面有一个ctrip函数。同样的原理也可以扩展到多层嵌套,比如三层和四层。n层,这些层形成链状结构。

从图中可以看出,我在携程下定义了另一个平面函数,所以有三层,输出结果就是我们想要看到的。每个层的名称只在它自己的范围内

它在内部生效,但有一个问题。有一天,我傻了。在定义平面的函数时,我忘了在var name='third '中写var。这时,在飞机上,

名字的价值是什么?是第一还是第二?复制代码如下:var name=' first函数ctrl IP(){ var name=' second ';函数平面(){ name=' thirdconsole.log(名称);} plane();console.log(名称);}携程网();console.log(名称);

现在是一个测试,看你是否真正理解范围链。仔细想想就会发现,当代码执行到平面函数中的name=“third”时,发现平面函数中并不存在局部变量名,代码恰好在携程函数中。所以解析器会回到携程函数去找名字,发现有名字。这时,携程的名字改为“第三”。

又有一天,喝多了酒,出丑了。定义平面函数时,我把name='third '误写成nam=' third丢了个e,可以说是酒精。

这不是我的代码。那么解析器此时应该做什么呢?同理,回头看的时候发现携程并不存在,回到顶窗的时候发现还是不存在。

此时,解析器已经做了这样的处理。既然整个链条没有价值,你又赋了一个价值,我不能向你报错。多尴尬,我就简单给你一个窗下隐含的定义

nam变量,此时Nam实际上是一个全局变量。我们可以在窗口顶部的控制台上查看nam。

嗯,关于变量的东西太多了,没什么不寻常的,理解它们也没什么意义。

更多资讯
游戏推荐
更多+