JS闭包在这个例子中是如何工作的?

时间:2017-04-27 19:10:43

标签: javascript closures

我真的很想了解对下面提到的代码的非常详细的理解。 TIA。

var globalValue = 'Global Val';
var ref1,ref2;
function outer(){
    var outerValue = 'Outer Val';
    function inner(){
        var innerValue = 'Inner Val';
        function innermost(){
            var innermostVal = 'Inner most Val' ;
            console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
        }
        ref2 = innermost;
    }
    ref1 = inner;
}

outer();
ref1();
ref2();

1 个答案:

答案 0 :(得分:0)

关闭 - 保护气泡

让我们分解一下被问到的问题,知道你有耐心阅读详细的答案。 :)

下面,我们在全局级别定义一个函数outervar globalValue

outer函数中,我们定义了函数innerouterValue

inner函数内部,我们定义innerValue。要交叉验证inner函数是否可以访问所有变量,我们会记录globalValue, outerValue and innerValue。它记录所有三个值。

但是,如果我们尝试在该变量的词法范围之外的任何地方访问innerValue,它将失败。

    var globalValue = 'Global Val';
    function outer(){
        var outerValue = 'Outer Val';
        function inner(){
            var innerValue = 'Inner Val';
            console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
        }
        inner();
    }

    outer();

现在,我们将看到对闭包的更深入了解。 所以,在上面的例子中,我们已经证明了inner function的狡猾。 现在,如果我们在全局级别上调用内部,它将返回error,因为它是在outer函数内部本地定义的。解决这个问题的方法是声明一个全局变量ref并存储inner作为参考。

同时,JS引擎执行阶段开始。它调用outer(),并为outer函数创建执行上下文。它为execution stack函数创建outer

在函数outer的执行堆栈结束之前,它在全局变量inner中分配ref的值。 函数outer的执行堆栈现在已经结束。

即使global execution stack重新开始行动。我们可以通过存储在全局变量outer中的inner函数的引用来访问函数innerref的所有变量。你去,那是一个 closure

var globalValue = 'Global Val';
var ref;
function outer(){
    var outerValue = 'Outer Val';
    function inner(){
        var innerValue = 'Inner Val';
        console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
    }
    ref = inner;
}

outer();
ref();

下面我们再添加一个级别。这里有另一个函数innermost,它已在函数inner中定义。但是,必须有一个链条才能使closure起作用。

因此,函数值innermost首先传递给ref2,然后传递到outer函数。 inner的值传递给ref1。这可以防止泡沫破裂,即使在使用global level处的引用调用函数时,我们也可以访问所有变量。

var globalValue = 'Global Val';
var ref1,ref2;
function outer(){
    var outerValue = 'Outer Val';
    function inner(){
        var innerValue = 'Inner Val';
        function innermost(){
            var innermostVal = 'Inner most Val' ;
            console.log(globalValue + '\n' + outerValue + '\n' + innerValue);
        }
        ref2 = innermost;
    }
    ref1 = inner;
}

outer();
ref1();
ref2();