附录A:动态作用域

动态作用域是在代码运行时(而非编写时)动态确定作用域的模型。 先看下面的代码:

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

function bar() {
    var a = 3;
    foo();
}

var a = 2;

bar();

根据词法作用域规则,foo函数引用的变量a是全局变量a,所以输出结果是2。

动态作用域不考虑函数和作用域如何定义、定义在何处,而是强调他们 从哪里被调用。也就是说,动态作用域的作用域链基于调用堆栈而非代码中作用域的嵌套关系

因此,如果JavaScript具有动态作用域,当foo()被执行时,理论上上面的代码会输出3,而不是2。这是因为当foo()找不到变量a时,不是根据词法作用域规则去外一层作用域查找,而是沿着调用栈查找,去foo函数被调用的地方查找。而foo函数是在bar函数中被调用,因此会检查bar的作用域是否有变量a,最后放回3。

JavaScript本身没有动态作用域,但是有词法作用域。但是JavaScript可以通过this机制实现动态作用域。

关键点:词法作用域是编写代码时就确定的,而动态作用域(以及this)是在运行时才确定的。词法作用域关心的是函数被声明的位置,而动态作用域关心的是函数被谁调用。

results matching ""

    No results matching ""