先花几秒钟来思考一个无厘头的小问题,闭包会导致函数的作用域链发生变化吗?

我们结合下面的例子来分析一下。

var fn = null;
function foo() {
    var a = 2;
    function innnerFoo() {
        console.log(a);
    }
    fn = innnerFoo; // 将 innnerFoo的引用,赋值给全局变量中的fn
}

function bar() {
    fn(); // 此处的保留的innerFoo的引用
}

foo();
bar(); // 2

这个例子中,foo内部的innerFoo访问了foo的变量a。因此当innerFoo执行时会有闭包产生,这是一个比较简单的闭包例子。不一样的地方在于全局变量fn。fn在foo内部获取了innerFoo的引用,并在bar中执行。

那么innerFoo的作用域链会是怎么样的?我们先利用断点调试的方式在浏览器中观察一下,结果如下。

在这里我们需要特别注意的地方是函数调用栈(图右侧Call Stack)与作用域链(Scope)的区别。

因为函数调用栈其实是在代码执行时才确定,而作用域规则在代码编译阶段就已经确定,虽然作用域链是在代码执行时才生成,但是它的规则并不会在执行时发生改变。

所以这里闭包的存在并不会导致作用域链发生变化。

results matching ""

    No results matching ""