什么是作用域
在搞清楚作用域是什么之前,我们先提出几个疑问
(---素质三连---)
到底什么是作用域? 作用域有什么用? 为什么需要作用域?
带着疑问来看文章
作用域的定义
在Javascript的世界里,存在着很神奇的一个规则,它在引擎在解析语法时起到了非常关键的作用,它就是作用域,所以作用域是一套用于编译时的规则,用于告诉引擎当前变量在何处,如何查找变量。
作用域有什么用
在JS代码被执行时,首先会对代码进行编译分析,语法解析,然后生成引擎可读代码运行,其中有三个关键的东西,引擎(负责整个代码运行过程)、编译器(辅助引擎进行代码分析)、作用域(用于维护标识符即变量,组成一套引擎可读懂的查询规则),以下面简单的代码为例
var a = 5
var b = a + 20
console.log(b) // 25
如图中,在解析整个代码过程,编译器和作用域都会辅助引擎,在这个过程中,编译器会对代码进行分词,关键字,赋值操作会分开解析,所以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的作用域可以找到,就会引用,在非严格模式下,这个作用域调用就如下图
如图中,寻找变量从当前自己作用域开始寻找,一步步往上层作用域寻找,直到最上层如果都找不到就会做相应的措施(涉及lhs和rhs查询问题,有兴趣可以自己去了解),整个过程可以称之为作用域链,所以作用域在代码执行的过程中是非常重要的
作用域的分类
这里简单的说几种作用域的分类
词法作用域:书写代码时就决定了语法中标识符的作用域位置
函数作用域:函数内的作用域,可进行模块分割之类的操作
块作用域:为了代码更好的维护,es6新增了let、const关键词
最后~
还记得一开始的三个作用域的疑问了吗,希望看完这篇文章可以解答这三个疑问,也能让你更加了解作用域到底是什么~~~