【问题标题】:Behaviors of Javascript closures and global functionsJavascript 闭包和全局函数的行为
【发布时间】:2016-06-26 06:31:15
【问题描述】:

在学习 javascript 闭包时,我在 stackoverflow 上遇到了这个答案 https://stackoverflow.com/a/111111/3886155。 这是对闭包的一个很好的解释。 但是我对Example 4Example 5有些困惑。

我只是在这里复制整个sn-p:

示例 4:

var gLogNumber, gIncreaseNumber, gSetNumber;
function setupSomeGlobals() {
    // Local variable that ends up within closure
    var num = 666;
    // Store some references to functions as global variables
    gLogNumber = function() { console.log(num); }
    gIncreaseNumber = function() { num++; }
    gSetNumber = function(x) { num = x; }
}

setupSomeGlobals();
gIncreaseNumber();
gLogNumber(); // 667
gSetNumber(5);
gLogNumber(); // 5

var oldLog = gLogNumber;

setupSomeGlobals();
gLogNumber(); // 666

oldLog() // 5

在阅读了一些示例之后,我可以说,每当函数内部的函数执行时,它总是可以记住外部函数内部声明的变量。 我同意,如果这些闭包变量无论如何更新,它仍然是指新的变量值。 我在这个例子中的问题与var oldLog=gLogNumber;特别相关 调用setupSomeGlobals();后如何返回旧号码?

因为现在var num 已重置。那么为什么它不使用这个新的 num 值 666?

现在示例 5:

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) {
        var item = 'item' + i;
        result.push( function() {console.log(item + ' ' + list[i])} );
    }
    return result;
}

function testList() {
    var fnlist = buildList([1,2,3]);
    // Using j only to help prevent confusion -- could use i.
    for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
    }
}

这里他们将函数推入数组并在循环结束后执行。但是现在引用闭包变量是循环结束后最新的。为什么不是旧的?

在这两个示例中,您只是将函数定义分配给变量或数组索引。但是第一个指向旧的,第二个指向最新的。为什么?

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    调用 setupSomeGlobals() 后如何返回旧号码

    num 不是全局范围的,因此值 num 位于调用 gLogNumber 引用的上下文中。

    再次调用setupSomeGlobals 方法后,对gLogNumber 的引用发生了变化。试试这个

    console.log(Object.is( gLogNumber, oldLog )); //true
    setupSomeGlobals();
    console.log(Object.is( gLogNumber, oldLog )); //false
    

    所以,oldLog 保留了旧的引用,因此保留了 num 的旧值,但 gLogNumber 得到了新的 num

    但是现在对闭包变量的引用是最新的 循环结束。为什么不是旧的?

    这个问题,看看

    JavaScript closure inside loops – simple practical example.

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 2015-11-24
      • 2015-06-13
      • 1970-01-01
      相关资源
      最近更新 更多