javascript - 一个 JavaScript 闭包混淆

标签 javascript closures

→ jsFiddle

function f1(){
    var n=999;

    nAdd=function(){n+=1;};

    function f2(){
        alert(n);
    }
    return f2;
}

var result = f1();
var result2 = f1();

result();  // 999
nAdd();
result2(); // 1000
result2(); // 1000
result();  // 999

我正在尝试学习 JavaScript 闭包,但上面的代码让我感到困惑。 当第一次调用 result() 时,它是 999。这对我来说没问题。

nAdd() 被调用后,result2() 显示 1000。我认为这是由于函数 result2() 和函数result() 等于函数 f1()

但为什么最后一个result()显示的是999而不是1000?

最佳答案

每次 f1() 被调用都会创建一个新的闭包,它有自己的本地 n 变量。

但是,nAdd 变量是全局变量,因此每次调用 f1() 时都会被覆盖 - 这意味着调用 nAdd()只会添加到 last 闭包中的 n 变量。

更新:如果您希望能够在每个闭包中独立地增加 n 的值,您可以这样做:

function f1(){
    var n=999;
    return {
        incrementN : function(){n+=1;},
        getN : function f2(){console.log(n);}
    }
}    
var result = f1();
var result2 = f1();
result.getN(); // 999
result.incrementN();
result2.getN();//999
result2.incrementN();
result2.getN();//1000
result.getN();//1000

也就是说,让 f1() 返回一个对象,其中包含两个未声明为全局变量的方法,并且这两个方法都对闭包中的局部 n 变量进行操作属于。

关于javascript - 一个 JavaScript 闭包混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19677879/

相关文章:

jquery - Google Closure 事件委托(delegate) a'la jQuery live/on

javascript - 在调用 sendToDevice 之前,将 Promise.All 与 Firebase Cloud Fxs 结合使用,用 FCM token 填充数组

javascript - Firefox OS 拨号网络事件

javascript - 在不打开的情况下编写 promise 然后调用

ios - 快速,延迟加载的简短闭包形式

swift - 如何在 Swift 中创建高阶函数?

Javascript deleteRow 导致indexSizeError,需要关闭

javascript - Javascript YouTube API使缩略图可单击

javascript - Node JS forEach 内存泄漏问题

c# - 如何在 C# 中正确释放匿名委托(delegate)/闭包?