function f1(){//2、找到 f1 函数,执行。
var n=999;//3、给变量 n 赋值。
nAdd=function(){n+=1}//9、找到 nAdd ,匿名函数内没有变量 n ,需要去上层查找,n = 999 +1。
function f2(){//5、找到 f2 函数,执行。
alert(n);//6、执行动作。
}
console.log(n);//新加上,测试,不参与执行步骤。
return f2;//4、返回 f2 函数,需要寻找 f2 函数。
}
var result=f1();//1、将 f1函数的返回值赋值给 result 变量,result 也变成函数,需要寻找f1函数。
result(); //7、第一次执行 result 函数,将步骤 6 的执行动作(步骤 6)结果输出,n 等于 999。
nAdd();//8、执行 f1 函数里的全局变量函数 nAdd ,需要寻找 nAdd 函数。
result(); //10、第二次执行 result 函数,将步骤 5 的执行动作(步骤 6)结果输出,此时 n 等于 1000,因为第一次执行 result 函数时,查找了上层的作用域,n 是 999。
nAdd();//11、如果再执行 nAdd 函数,此时 nAdd 这个函数里的 n 是 1000,而 f1 函数的 n 还是 999,也就是说 f1 的变量 n 和 nAdd 的 n 是两个作用域不同的同名变量。
result();
f1();//新加上,测试
/*结果
控制台输出:999
弹窗:999
弹窗:1000
弹窗:1001
控制台输出:999
*/
Ich möchte Senioren bitten, zu prüfen, ob dieses Verständnis richtig ist.
Ergänzung: Kann man verstehen, dass bei der ersten Ausführung des Abschlusses nach der Variablen in der oberen Ebene gesucht werden muss, nachdem der Variablenwert in der oberen Ebene zum Variablenwert der Unterfunktion wird? In Zukunft ist keine Suche in der oberen Ebene erforderlich, da diese bei der ersten Ausführung vererbt wurde und zu Ihrer eigenen wird.
Es fühlt sich ein bisschen chaotisch an. . .
(Gesichtsbedeckung
-----------------------Erneut hinzugefügt------------------------------------- -
Je mehr ich es betrachte, desto verwirrender wird es.
Dann war es ein komplettes Durcheinander.
Den Ausgabeergebnissen, der ersten Konsolenausgabe und der letzten Konsolenausgabe nach zu urteilen, ist n von f1 unveränderlich.
Aber können Unterfunktionen keine Variablen voneinander lesen? Warum beeinflusst der Ausdruck von nAdd n von f2?
此时b和result中的n不是同一个
b和nAdd的n是同一个.
result的n已经无法改变.
有相同的问题,复制了下我的回答并添加些。
var result=f1()
:f1函数返回了f2函数把返回的f2函数赋值给result全局变量,(f2的作用域链保存到result全局变量中)
result()
:调用result(),这就形成闭包:有权访问另外一个函数作用域中的变量因为在f2中的作用域引用了f1中的n这个局部变量,当f1执行完毕后,垃圾回收机制发现n变量还在被result中引用所以垃圾回收机制不会把n回收释放。
以至于n一直保存在result作用域链中。result的作用域链正常能访问f1中的局部变量n,形成闭包。
nAdd()
:nAdd没有写var所以nAdd是全局变量,在调用nAdd()和result()是一样的都会形成闭包,匿名函数function(){n+=1}的作用域链中有n这个局部变量,所以当nAdd=funtion(){n+=1}时,这个匿名函数的作用域链保存到了全局变量nAdd形成闭包,调用nAdd()作用域链中找到f1局部变量n=999,n+1=1000。result()
:result()就输出1000nAdd();重复第三步骤 n+1 = 1001
result();重复第四步骤 输出n
f1();调用f1时并没有形成闭包,n永远都是999,因为每次f1执行结束后n都被垃圾回收机制销毁了,所以这里再次调用 var n=999;后面输出也都是999
为什么 nAdd 的表达式会影响到 f2 的 n?
因为闭包的原因n一直都没被销毁,nAdd()也形成了闭包,并改变了n的值,所以后面再次调用result() n没被销毁回收一直被+1,所以会被影响。
最后在调用f1()时没有闭包,之前n是被销毁了。所以一直输出a=999;
只是本人理解,如有错误请拍砖告知
建议你看下这个
http://www.ruanyifeng.com/blo...
上面解释得比较清楚
说的太复杂了吧
这个闭包就是利用了js 的 static scope的特性实现的这个效果
第一次调用result():
alert(n); 寻找的是 n1
nAdd(); 增加的也是n1的值
后面的也是这样
而最后一次 f1();
运行的时候 var n = 999; 赋值的也是n1
其中console.log(n) 的n 也是n1 所以打印出的就是999
你这个例子有点简单,你可以看一个复杂的例子(重点看其中static scope)的说明:
static scope