JavaScript闭包混乱

Coo*_*Guy 34 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
Run Code Online (Sandbox Code Playgroud)

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

之后nAdd()被调用,result2()显示1000我认为这是由于功能result2()和作用result()是等于功能f1().

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

nnn*_*nnn 36

每次f1()调用都会创建一个具有自己的局部n变量的新闭包.

但是,nAdd变量是全局变量,因此每次f1()调用nAdd()都会被覆盖- 这意味着调用只会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
Run Code Online (Sandbox Code Playgroud)

也就是说,f1()返回一个包含两个未声明为全局变量的方法的对象,并且它们都对n它们所属的闭包操作局部变量.


Ken*_*Kin 27

已经有了很好的答案,但我想一张照片有助于理解.

在此输入图像描述

  • 终于点击了.谢谢你的可视化 (2认同)

Que*_*tin 13

每次你打电话给f1()你:

  • 创建一个名为nvalue的新(本地)变量999
  • 创建一个分配给全局 的新无名函数nAdd,修改该n函数(并覆盖分配给的任何先前函数nAdd)
  • 创建一个返回的新函数,该函数会警告其值 n

你打了f1()两次电话,所以你做了两次这样的事.第二次调用它时,nAdd用一个修改第二个 的新函数覆盖n.

这让你:

  • result()提醒第一个 n
  • result2()提醒第二个 n
  • nAdd()增加第二个 n

result()在最后一行警报,999因为它警告第一 行的值n(从未增加).

  • 变量*nAdd*创建一次:第一次在评估赋值语句时调用*f1*.之后,它只是每次调用*f1*时更改的值.也许这只是说你说的话的另一种方式.: - / (2认同)