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
*/
想請教各位前輩看看這樣的理解是不是正確的。
補充:可不可以理解為,閉包第一次執行的時候需要往上層查找變量,找到之後,上層的變量值就變成了子函數的變量值,以後就不需要再去上一層查找,因為已經在第一次執行的時候繼承了,變成自己的。
感覺有點亂。 。 。
(摀臉
--------------------再補充--------------------
越看越亂。
然後徹底亂了。
從輸出結果來看,第一次控制台的輸出和最後一次控制台的輸出,f1的 n 是不可變的。
但是子函數之間不是不能互相讀取變數嗎?為什麼 nAdd 的表達式會影響到 f2 的 n?
此時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