前段时间一直想抽空把《你不知道的JS》给看一看,准备好好巩固JS的基础,于是现在有了这篇文章.
1.两个问题
- 为什么讲作用域?
- 讲作用域是因为大多数编程语言中,作用于都是非常关键的一环,它所提供的功能给我们编程程序的时候带来极大的便利!
- 作用域在JS中的作用是什么?
- 一套良好的规则来存储变量,并且与此同时,可以方便的找到变量,这套叫做作用域!
看到这里的你,是不是以为现在就已经将我要讲的内容已经简单阐述完了,其实不是的,讲到这里其实是为了我们更好地理解作用域而做的铺垫.
2.编译原理
在我们学习JavaScript的过程中,常常看到书中提到几个比较鲜明的字眼,动态类型,解释型的编程语言!但是在本文中,我要说的是,JavaScript是一门编译类型的语言,尽管和你看到的Java等常见的编译类型语言不同!
- 并非提前编译
- 编译后的结果不能够在分布式中进行移植
这两点适合传统的编译类型语言所不同的!虽然说JavaScript引擎编译和传统的编译语言步骤非常相似,但是在某些环节中比预想的还要复杂!
传统编译语言流程中在执行前会经历的三个步骤,称为"编译"
st=>start: start
op1=>operation: 1.分词/词法解析
op2=>operation: 2.解析/语法解析
op3=>operation: 3.代码生成
e=>end: end
st->op1->op2->op3->e
01编译.png
那么对应的流程图中的概念如何理解呢?
其实对应的也就是三个概念,我也只是结合自身的理解和书中的观点,进行简单阐述:
- 分词/词法分析
- 该过程会将字符串分割成为有意义的代码块! 至于说空格是否有意义,取决于空格在编程语言中是否有意义!
- 其中有意义的代码块被称之为 词法单元!
- 解析/语法分析
- 该过程会将词法单元流(组)转换成为一个元素逐级嵌套组成代表程序语法结构的树!
- 该树 被程序员们称之为 AST(Abstract Syntax Tree) 抽象语法树!
- 代码生成
- 将对应的AST转换为可执行代码的过程!
- 对应的过程,与语言,目标平台息息相关!
对应的比起编译过程只有三个步骤的语言的编译器而言,JavaScript引擎则复杂得多.
- 在语法分析和代码生成阶段有特定的步骤对运行性能进行优化! 例如:对冗余元素进行优化!
- JavaScript引擎不会有大量的时间进行优化,JS与别的语言不同的是,JS编译过程不是发生在构建之前的!
-
编译发生在JS执行前几微秒,在作用域背后,JS引擎用了九牛二虎之力保证性能,其中包括以下几点:
- JIT(Just In Time 即时编译)
- 延迟编译
- 实施重编译
3.理解作用域
- 引擎 从头至尾负责JS程序的编译和执行过程
- 编译器 负责语法分析和代码生成
- 作用域
- 收集&维护 查询(由声明的标识符组成!)
- 一套规则 确定当前执行代码对标识符的访问权限!
首先我们看段代码:
var a = 2;
-
通过查看这段代码,有几次声明?
- 编译器编译时的处理
- 引擎运行代码时处理
-
编译器是如何处理的呢?
- 当开始遇到
var a
的时候,编译器询问 作用域是否有一个该名称的变量存在于作用域的集合中!- 有的话 忽略声明 继续进行编译操作!
- 否则 在当前作用域中的集合中生命新的变量!
- 之后为引擎生成运行时所需的代码!
- 当开始遇到
-
引擎是如何处理的呢?
- 引擎会询问作用于是否存在对应的变量,如果存在的话,使用该变量,否则继续查找该变量,该变量找不到的话就会报错!
-
变量赋值操作会执行的两个动作
- 编译器在当前作用域中声明一个变量(该变量存在的话!)
- 运行时引擎会在作用域中查找该变量,找到就为其赋值!
4.作用域嵌套
在前面的内容中就已经说到过,作用于其实是一套规则,根据名称查找变量的一套规则,但是实际情况中还是很难避免需要同时估计几个作用域!
当一个块或者函数嵌套在另外一个快或者函数中,就发生了对应的作用于嵌套,因此当我们查找某一个变量的时候无法找到的情况下,引擎就会向外层作用域查找,直到抵达最外层的作用域(全局作用域)为止!
foo(a){console.log(a + b);}
var b = 2;
foo(2);
其实通过这个例子就很明白的知道,在函数 foo中无法找到变量b,但是foo又是存在于全局作用域之下和b在同一个作用于,于是foo作用域找不到的变量在全局作用域中找到了!
遍历作用域链的规则其实很简单,引擎从当前的执行作用域中开始查找该变量,如果找不到的话,就会向上一级查找,直到抵达全局作用域的时候,无论还有没有找到,查找过程都会停止!
对应的我们为了更好的理解作用域的处理过程,嵌套作用域的处理过程向一个链条一样,此时这个链条就叫做作用域链!
如果你有更好的建议或者意见,请在留言区告诉我 _!
网友评论