Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript闭包混乱_Javascript_Closures - Fatal编程技术网

JavaScript闭包混乱

JavaScript闭包混乱,javascript,closures,Javascript,Closures,我试图学习JavaScript闭包,但上面的代码让我感到困惑。 第一次调用result()时,是999。对我来说没关系 调用nAdd()后,result2()显示1000。我认为这是由于函数result2()和函数result()等于函数f1() 但是为什么最后一个result()显示的是999而不是1000?result和result2包含不同调用f1的结果,因此包含局部变量n的不同实例。函数的每次调用对于该函数的局部变量可能有不同的值。这甚至适用于不涉及闭包的情况。每次调用f1()时,它都会

我试图学习JavaScript闭包,但上面的代码让我感到困惑。 第一次调用
result()
时,是999。对我来说没关系

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


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

result
result2
包含不同调用
f1
的结果,因此包含局部变量
n
的不同实例。函数的每次调用对于该函数的局部变量可能有不同的值。这甚至适用于不涉及闭包的情况。

每次调用
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

也就是说,have
f1()
返回一个对象,该对象包含两个未声明为全局的方法,并且都对它们所属闭包中的本地
n
变量进行操作。

每次调用
f1()
时,您:

  • 创建一个名为
    n
    的新(本地)变量,其值为
    999
  • 创建分配给全局
    nAdd
    的新匿名函数,该函数修改
    n
    (并覆盖以前分配给
    nAdd
    的任何函数)
  • 创建一个返回的新函数,该函数会提醒该
    n
您调用了两次
f1()
,所以所有这些都要调用两次。第二次调用它时,将使用一个新函数覆盖
nAdd
,该函数修改第二个
n

这就给您留下了:

  • result()
    首先向发出警报
    n
  • result2()
  • nAdd()
最后一行的
result()
会发出警报
999
,因为它会警报第一个
n
的值(该值从未递增)。

nAdd=function(){n+=1;}行创建一个全局函数,它是
f1()
中的一个闭包。闭包也可以访问创建它的函数范围中的所有变量。因此,每次调用
f1()
时,它都会创建一个新的
nAdd()
函数,该函数的
n
值绑定到
f1()调用的
var n

在代码中

var result = f1();
var result2 = f1();
result(); // 999
nAdd();         // Created by "var result2 = f1();" and has the same 'n' value as function in result2
result2();//1000
result2();//1000
result();//999

result和result2使用不同的n创建两个不同的闭包。如果通过在f1()函数之外声明n使其成为全局变量,则会得到预期的结果,因为在这种情况下,您将始终访问全局变量n:

var n=999; 函数f1(){
nAdd=函数(){n+=1;};
函数f2(){
console.log(n);
}
返回f2;
}
var result=f1()
var result2=f1()
结果();//999
nAdd()
结果2()//1000
结果2()//1000
结果()//1000


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

它是这样的:

var nAdd;
function f1(){
    var n=999;

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

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

var result = f1();//var nAdd=function(){n+=1;} n=result.n=999

var result2 = f1();//var nAdd=function(){n+=1;} n=result2.n=999

var result3 = f1();//var nAdd=function(){n+=1;} n=result3.n=999

nAdd();

result();  // 999

result2(); // 999

result3(); // 1000

var result = f1();//var nAdd=function(){n+=1;} n=result.n=999

var result2 = f1();//var nAdd=function(){n+=1;} n=result2.n=999

nAdd();

var result3 = f1();//var nAdd=function(){n+=1;} n=result3.n=999


result();  // 999

result2(); // 1000

result3(); // 999

var result = f1();//var nAdd=function(){n+=1;} n=result.n=999

var result2 = f1();//var nAdd=function(){n+=1;} n=result2.n=999

nAdd();

var result3 = f1();//var nAdd=function(){n+=1;} n=result3.n=999
nAdd(); 
nAdd();
nAdd();   

result();  // 999

result2(); // 1000

result3(); // 1002

+1.每次输入执行上下文时,都会创建一组新变量。变量nAdd创建一次:第一次在赋值语句求值点调用f1。之后,每次调用f1时,值都会更改。也许这只是你说话的另一种方式-/我猜这家伙展示了3个片段,每个片段都以代码“result3();”结尾。那就可以理解了。是的!比其他答案更清楚请相信最好的答案!!解释得很清楚!非常感谢。还有一个简单的问题:为什么语句
returnf2
会导致调用
f2
?(不
f2()
)@Bao
返回f2
不会导致调用f2;调用是因为调用了
result
result2
var nAdd;
function f1(){
    var n=999;

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

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

var result = f1();//var nAdd=function(){n+=1;} n=result.n=999

var result2 = f1();//var nAdd=function(){n+=1;} n=result2.n=999

var result3 = f1();//var nAdd=function(){n+=1;} n=result3.n=999

nAdd();

result();  // 999

result2(); // 999

result3(); // 1000

var result = f1();//var nAdd=function(){n+=1;} n=result.n=999

var result2 = f1();//var nAdd=function(){n+=1;} n=result2.n=999

nAdd();

var result3 = f1();//var nAdd=function(){n+=1;} n=result3.n=999


result();  // 999

result2(); // 1000

result3(); // 999

var result = f1();//var nAdd=function(){n+=1;} n=result.n=999

var result2 = f1();//var nAdd=function(){n+=1;} n=result2.n=999

nAdd();

var result3 = f1();//var nAdd=function(){n+=1;} n=result3.n=999
nAdd(); 
nAdd();
nAdd();   

result();  // 999

result2(); // 1000

result3(); // 1002