第一章 作用域的初步理解

1.作用域是什么

1.1  编译原理

 
通常将JavaScript归类为“动态”或“解释执行”语言,但事实上是一门编译语言。但与传统的编译语言不同,它不是提前编译的。
 
在传统的编译语言的流程中,代码在执行前会经历三个步骤:
1. 分词/词法分析
2.解析/语法分析
    将词法单元流转换成一个由元素逐级嵌套组成的抽象语法树(AST)
    eg. var a = 2;
        顶级节点:VariableDeclaration
                                   ↓
                   Indetifier(a)        Assignment
                                                  ↓            
                                         Numericiteral(2)        
3.代码生成    
    AST→可执行代码

JavaScript的编译原理

编译发生在代码执行前几微秒,甚至更短
任何Javascript代码片段在执行前都要进行编译(通常就在执行前)。Javascript编译器会首先对var a = 2;这段程序进行编译,然后做好执行它的准备,并且通常马上就会执行它。
 

1.2  理解作用域

主角:
   引擎  --  负责整个js程序的编译及执行
   编译器  -----  负责语法分析及代码生成
   作用域  -----  是根据名称查找变量的规则,确定当前执行的代码对标识符的访问权限。当变量出现在赋值操作的左侧进行LHS查询,出现在右侧时进行RHS查询。如果查找的目的是对变量赋值,则会使用LHS查询,如果目的是获取变量的值,就会使用RHS查询
        eg.  var a = 2; 引擎会认为有两个完全不同的声明,一个由编译器在编译时处理,一个由引擎在运行时处理。
        变量的赋值操作会执行两个动作。
         1.首先编译器会在当前作用域声明一个变量(如果之前没有声明过)
         2.接下来,a=2会查询(LHS)变量a并对其进行赋值。
        

1.3  作用域嵌套

 
当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。在当前作用域中无法找到某个变量时,引擎就会向上级作用域继续查找,每次上升一级作用域,直到找到该变量,或抵达最外层的作用域(全局作用域)为止。
 

1.4  异常

 
RHS:  如果RHS查询在所有嵌套的作用域中找不到所需变量,引擎会抛出ReferenceError异常。
LHS:   当引擎在执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标变量,非严格模式下,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎;ES5中引入了严格模式,严格模式禁止自动或隐式创建全局变量。因此,在严格模式下查询失败时,引擎会抛出同RHS查询失败时类似的ReferenceError异常。
 
接下来,如果RHS查询到了一个变量,但当尝试对这个变量的值进行不合理的操作时(比如引用null或undefined类型的值中的属性),引擎会抛出TypeError异常。
 
总结:ReferenceError同作用域判别失败相关,TypeError则代表作用域判别成功,但对结果的操作是非法或不合理的。
 
 
 
 
 
 
 
 
 
 





posted @ 2017-03-02 09:09  夏目233  阅读(169)  评论(0编辑  收藏  举报