第1章 作用域是什么

  • 作用域:是说明如何存储变量,以及如何查找这些变量的规则;
编译原理
编译过程
  • 分词或词法分析(tokening或lexing)
    • 将代码字符串分解成有意义的代码块,这些代码块称为词法单元;
  • 解析或语法分析(parsing)
    • 将所有词法单元转换成由元素逐级嵌套组成的抽象语法树AST,AST代表了程序的语法结构;
  • 代码生成
    • 将AST转换为一组机器指令;
javascript的编译
  • javascript执行之前是进行编译的,编译发生在执行之前的很短时间之内;
作用域
术语
  • 引擎:负责整个javascript程序的编译和执行过程;
  • 编译器:负责语法分析和代码生成;
  • 作用域:负责收集并维护对所有声明变量的查询,按照规则确定当前执行的代码对这些变量的访问权限;
变量声明并赋值的过程
  • 引擎在执行var a=2;语句时,包含两个过程:
    • var a由编译器进行处理,编译器会查询作用域中是否已存在该变量:
      • 如果变量不存在会在当前作用域中声明新变量,命名为a;
      • 如果变量已存在,声明会被忽略;
    • 编译器会将a=2转换为机器码,并由引擎运行;
      • 引擎在运行该代码时,首先查询作用域是否存在a变量,如果存在就会使用该变量,将2赋值给a;
      • 如果不存在a变量,引擎会继续查找,如果最终没有找到该变量,将抛出异常;
LHS查询和RHS查询
  • RHS:简单的查询变量的值;
    • 当变量作为赋值的源时进行RHS查询;
  • LHS:查找变量的内存地址(?)以便对其进行赋值;
    • 当变量作为赋值目标时,执行LHS查询;
    • 执行LHS查询时,并不关系变量本身的值;
  • 在执行变量赋值如var b=a时:
    • 对a进行RHS查询,取得a的值;
    • 再对b进行LHS查询,取得b的内存地址,并将a的值保存到该地址;
  • 函数调用时,首先对函数进行RHS查询,实参到形参的传递涉及对形参的LHS查询;
  • function foo(a){}不能理解成var foo=function(a){}这样的LHS查询和赋值形式;
作用域链
  • 当一个函数嵌套在另一函数中时,就发生了作用域的嵌套,在当前作用域中无法找到某个变量时,引擎就会在外层作用域中继续查找,直至到达全局作用域,这些嵌套的作用域称为作用域链;
异常
  • 在变量未声明时,进行两种查询的行为是不一样的;
  • 对一个未声明的变量进行RHS查询时,引擎会抛出ReferenceError异常;
  • 对一个未声明的变量进行LHS查询,会导致在全局作用域创建该变量;
    • 只在非严格模式下可行,在严格模式下对未声明变量进行LHS查询,同样会导致ReferenceError异常;
  • 对一个变量成功进行了RHS查询之后,如果对变量值进行不合理的操作会导致TypeError异常;
 
posted @ 2016-04-14 16:13  青鹤  阅读(181)  评论(0编辑  收藏  举报