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