作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。
    如果查找的目的是对变量进行赋值,那么就会使用LHS查询;
    如果目的是获取变量的值,就会使用RHS查询。

    赋值操作符会导致LHS查询。=操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。

    JavaScript引擎首先会在代码执行前对其进行编译,在这个过程中,像var a = 2这样的声明会被分解成两个独立的步骤:
    1.首先,var a在其作用域中声明新变量。这会在最开始的阶段,也就是代码执行前进行。
    2.接下来,a = 2会查询(LHS查询)变量a并对其进行赋值。

    LHS和RHS查询都会在当前执行作用域中开始,如果有需要(也就是说它们没有找到所需的标识符),就会向上级作用域继续查找目标标识符,这样每次上升一级作用域(一层楼),最后抵达全局作用域(顶层),无论找到或没找到都将停止。

    不成功的RHS引用会导致抛出ReferenceError异常。
    不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出ReferenceError异常(严格模式下)。
    ReferenceError同作用域判别失败相关,而TypeError则代表作用域判别成功了,但是对结果的操作是非法或不合理的。
    如果RHS查询找到了一个变量,但是你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值中的属性,那么引擎会抛出另外一种类型的异常,叫作TypeError。