songStar0904/You-don-t-know-JavaScript

第一部分 作用域和闭包 第一章----作用域是什么

Opened this issue · 0 comments

1.1编译原理

编译的三个步骤:

  • 分词/词法分析。
    这个过程会将由字符组成的字符串分解成有意义的代码块,这些代码块被称为此法单元。例如:var a = 2会被分解成var, a, =, 2, ;。空格是否会被当作词法单元,取决于空格在这门语言中是否具有意义。
  • 解析/语法分析
    这个过车工是将词法单元流(数组)转换成一个由元素主机嵌套所组成的代表了程序语法结构的树。这个树被称为“抽象语法树”(Abstract Syntax Tree, AST)。
  • 代码生成
    将AST转化成可执行代码的过程。

1.2理解作用域

1.2.1 演员表

  • 引擎
    从头到尾负责整个JavaScript程序编译及执行过程。
  • 编译器
    负责语法分析及代码生成的脏活累活
  • 作用域
    负责收集并维护有所有生命的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

1.2.2 对话
var a = 2; 编译器进行如下处理

  1. 遇到var a,编译器会询问作用域是否已经存在一个该名称的变量存在于同一个作用域的集合中,如果是,编译器会忽略该声明,继续进行编译;否则他会要求作用域在当前作用域的集合中声明一个新的变量a。

  2. 接下来编译器会为引擎生成运行时所需的代码,这些代码被用来处理a = 2这个赋值操作。引擎运行时首先询问作用域,在当前作用域是否存在变量a,如果存在则会使用这个变量,否则继续查找该变量。最后会访问全局作用域还没有找到该变量,则会抛出一个异常。
    1.2.3 LHS和RHS查询
    定义:当变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询。
    讲的更准确一点,RHS查询与简单地查找某个变量的值别无二致,而LHS查询则是视图找到变量的容器本身,从而可以对其赋值。LHS就是对一个变量进行赋值,RHS理解成取到它的源值

function foo(a){
  console.log(a); // 2
}
foo(2);

在这段代码中,既有LHS又有RHS。首先,执行foo函数的时候,参数2赋值给a,这里是LHS查询。然后console.log(a);输出a的时候,变量a要去找它的值(取它的源值)那么也就是RHS查询。

1.3 作用域嵌套

遍历嵌套作用域链的规则很简单:引擎从当前的执行作用于开始查找变量,如果找不到就向上一级继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都结束。