什么是作用域

编译原理

传统编译语言

  • 词法分析:将由字符组成的字符串分解成(对编译语言来说)有意义的代码块,这些代码块被称为词法单元。
  • 解析/语法分析:将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树,即“抽象语法树”(abstract syntax tree,AST)。
  • 代码生成:将AST转换成可执行代码的过程被称为代码生成。这个过程与语言、目标平台等息息相关。

相比只有三个步骤的语言的编译器,javascript引擎要复杂的多。例如,在语法分析和代码生成阶段有特定的步骤来对运行性能进行优化,包括对冗余元素进行优化。简单的说,任何javascript代码片段在执行前都要进行编译(通常就在执行前)

理解作用域

  • 程序处理过程中的角色:
    1.引擎
    从头到尾负责整个javascript程序的编译和执行过程
    2.编译器
    负责语法分析及代码生成等脏活累活
    3.作用域
    负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
    简单的说:作用域是一套规则,用于确定在何处以及如何查找变量(标识符)
  • 变量的赋值操作
    var a=2;
    会执行两个动作,首先编译器会在当前作用域声明一个变量(如果之前没有声明过),然后运行时引擎会在作用域中查找该变量,如果能够找到就会对他赋值:

1.编译器在编译过程的第二步中生成了代码,引擎执行它时,会通过查找变量来判断它是否以声明过,查找的过程由作用域进行协助。

2.引擎有两种查找类型:(1)如果查找的目的是对变量进行赋值,那么就会使用LHS查询,(2) 如果目的是获取变量的值,就会使用RHS查询。这两种查询都会在当前执行作用域中开始,如果他们没有找到所需的标识符,就会向上级作用域继续查找目标标识符,最后抵达全局作用域,这时候无论找不找的到都将停止。

3.不成功的RHS引用会导致抛出ReferenceError异常:在所有嵌套的作用域中遍寻不到所需的变量。不成功的LHS引用会导致自动隐式创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出ReferenceError异常(严格模式下)

4.如果RHS查询找到了一个变量,但你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值中的属性,那么引擎会抛出另外一种类型的异常,叫做TypeError。ReferenceError同作用域判别的失败相关,而TypeError则代表作用域判别成功了,但是对结果的操作是非法或不合理的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容