深入理解JavaScript (4) —— 从自由变量到作用域链

自由变量:如果在某个作用域中使用了变量“a”,而变量“a”并未在该作用域中声明(在其它作用域中声明了),则该变量“a”即为自由变量。

var a = 1;
function fn() {
    var b = 2;
    console.log( a + b);    //变量a即为一个自由变量
}

上述代码中,取b的值就直接可以在fn作用域中取,因为b就是在这里定义的。而取x的值时,就需要到另一个作用域中取。到哪个作用域中取呢?

有人说,要到父作用域中取,其实有时候这种解释会产生歧义。例如:

var a = 1;
function fn() {
    console.log(a);
}

function show(f) {
    var a = 2;
    (function () {
        f();    //1,而不是2
    })();
}

show(fn);

上述代码的执行结果说明“要到父作用域中取”这句话并不准确,更贴切的说法是:要到创建这个被执行函数(此处为fn)的那个作用域(此处为全局作用域,因为fn是在全局作用域中创建的)中取值 是“创建”,而不是“调用”,切记切记——其实这就是所谓的“静态作用域”。换言之,此处最终执行的函数是fn,而自由变量是a,因此要到创建fn的作用域中去找a的值。

存在这样的可能,在创建fn的作用域中并未找到自由变量a,此时怎么办呢?那就再到该作用域的上一级作用域中寻找,如若还没有,就继续向上找,直至找到全局作用域,若依然未找到,就会报“a is not defined!”。能够沿着作用域一级级向上寻找的机制就称为“作用域链”。

你可能感兴趣的:(作用域链,javascript)