关键词
作用域 定义时 变量查找规则 赋值操作基于作用域查找规则 查找目标的值也是基于作用域查找规则
作用域规则
JavaScript作用域是定义时的概念,用于确定在何处以及如何查找变量(标识符),如果是对变量的赋值操作就会进行LHS查询,如果是获取变量的值就会进行RHS查询。
深入理解”定义时”概念
两个函数唯一的区别:在于函数体内部的变量x是否用var重新声明.
当使用默认参数的时候,参数会形成一个单独的作用域,等到初始化结束,这个作用域就会消失。
|
|
代码的执行过程:参数初始化过程和函数体代码执行过程
对于例1很容易得出错误的结果foo(); // 3 x; // 1
错误的原因就是:对于作用域是定义时概念理解得不深刻。
|
|
对于例2,因为没有用var重新声明一个同名变量,此时函数体内的x指向参数x,y赋值操作的目标也是参数x,两个x是同一个x,所以y()赋值成功。
关于为什么会错误理解
因为时常弄混淆静态作用域和动态this
动态作用域
JavaScript中的作用域是词法作用域
词法作用域是一套关于引擎寻找变量以及会在何处找到变量的规则。词法作用域最最最最重要的特征是它的定义过程发生在代码的书写阶段(假设你没有使用eval()或with)
动态作用域似乎暗示有很好的理由让作用域作为一个在运行时就被动态确定的形式,而不是在写代码时进行静态确定的形式。
|
|
词法作用域让foo()中的a通过RHS引用到了全局作用域中的a,因此会输出2.
而动态作用域并不关心函数和作用域是如何声明以及在何处声明的,只关心它们从何处调用。换句话说,作用域链是基于调用栈的,而不是代码中的作用域嵌套。动态作用域的查找结果导致a为3.
简单总结区别
词法作用域是在写代码的时候或者说定义时确定的,而动态作用域是在运行时确定的,(this也是!) 词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用。