一文了解作用域到底是什么

97 阅读4分钟

73295ceea5ec4d77a3cd5fcfa3c5cea.jpg

什么是作用域

在搞清楚作用域是什么之前,我们先提出几个疑问

(---素质三连---)

到底什么是作用域作用域有什么用为什么需要作用域

带着疑问来看文章

作用域的定义

在Javascript的世界里,存在着很神奇的一个规则,它在引擎在解析语法时起到了非常关键的作用,它就是作用域,所以作用域是一套用于编译时的规则,用于告诉引擎当前变量在何处,如何查找变量。

作用域有什么用

在JS代码被执行时,首先会对代码进行编译分析,语法解析,然后生成引擎可读代码运行,其中有三个关键的东西,引擎(负责整个代码运行过程)、编译器(辅助引擎进行代码分析)、作用域(用于维护标识符即变量,组成一套引擎可读懂的查询规则),以下面简单的代码为例

var a = 5
var b = a + 20

console.log(b) // 25

image.png

如图中,在解析整个代码过程,编译器和作用域都会辅助引擎,在这个过程中,编译器会对代码进行分词,关键字,赋值操作会分开解析,所以var a = 5会变成var a 和 a = 5进行分析,而作用域在这之中就是对代码中用到的变量提供定位,整个过程可以模拟成以下对话

引擎大哥:兄弟们,我要开始解析这段代码啦
编译器:好的大哥,我先帮你把代码分析分析,loading.....,大哥分析好了
引擎大哥:好的,让我看看这段哈var a,var b,作用域老弟,我这段代码需要用到a 和 b变量,你这里有没有帮我找一下,没有的话我就帮他创建了
作用域:大哥,我这里没有,你创建一个把,我记录一下
引擎大哥:好的,我创建了a 和 b变量,作用域你帮我记一下哈,栓q了
作用域:好的大哥,已经记录了
引擎大哥:那我继续了,我看这段a = 5,那我再问问作用域小弟,麻烦你那边帮我把a的位置找出来,我要给他赋值了
作用域:好的大哥,我这里有个a,你就用它吧
引擎大哥:好的谢谢,那我们再接再厉b = a + 20,作用域小弟,这里我需要找到b变量和a变量的值,麻烦再帮我找找
作用域:没问题,都交给我,找到了大哥,b变量是在这个位置,而a的值是5哦
引擎大哥:栓q了哥们

可以看到在整个过程中,作用域的功能就是查到对应变量的位置和值,这就是作用域工作

为什么需要作用域

上面了解到作用域作用后,那我们聊聊为什么需要作用域

在代码解析过程中,存在作用域调用问题,即标识符(变量)在哪里,什么情况下可以用的问题

function test (a) {
    var b = 10
    function test1 (c) {
        console.log(a+b+c)
    }
    test1(5)
}
test(5) // 20

该段代码存在三个作用域,全局作用域(包含了test函数),test函数作用域(包含了变量a、b和test1函数)、test1函数作用域(包含c变量)

在上面代码运行时,用到的变量会寻找对用作用域的变量,如果寻找不到,会往上一层寻找,直到最后为全局作用域为止,举例代码中的console.log(a+b+c)这一段,里面用到的a,b变量在test1作用域中不存在,就会往上一层test的作用域寻找,在test的作用域可以找到,就会引用,在非严格模式下,这个作用域调用就如下图

image.png

如图中,寻找变量从当前自己作用域开始寻找,一步步往上层作用域寻找,直到最上层如果都找不到就会做相应的措施(涉及lhs和rhs查询问题,有兴趣可以自己去了解),整个过程可以称之为作用域链,所以作用域在代码执行的过程中是非常重要的

作用域的分类

这里简单的说几种作用域的分类

词法作用域:书写代码时就决定了语法中标识符的作用域位置
函数作用域:函数内的作用域,可进行模块分割之类的操作
块作用域:为了代码更好的维护,es6新增了let、const关键词


最后~

还记得一开始的三个作用域的疑问了吗,希望看完这篇文章可以解答这三个疑问,也能让你更加了解作用域到底是什么~~~