javascript閉包問題
阿新 • • 發佈:2018-03-10
方法 col 例子 pos function urn 引用 10個 fun
什麽是閉包??
有權訪問另一個函數作用域內變量的函數就是閉包。
看一個例子:
1 function a(){ 2 var n = 0; 3 function inc(){ 4 n++; 5 console.log(n); 6 } 7 return inc; 8 } 9 var c = a(); 10 c(); //控制臺輸出1 11 c(); //控制臺輸出2
在這裏,控制臺兩次輸出不一樣???為什麽??變量n不是重新賦值了嗎??
並沒有,在這裏,var c = a(); 這段代碼意思是將 a 方法的返回值賦值給變量 c ,那麽 a() 的返回值就是 inc ,也就 function inc() ,
後面執行兩次 c(); c(); 實際上是執行兩次的 inc(); 因為function一直引用著a(),所以n沒有回收,也就是說,n的值一直在用著,
自然第一次執行 c() 打印1,第二次執行 c() 打印2;
再看一個經典例子:
1 function createFunctions(){ 2 var result = []; 3 for (var i=0; i < 10; i++){ 4 result[i] = function(){ 5 return i; 6 }; 7 } 8 return result; 9 }10 var funcs = createFunctions(); 11 for (var i=0; i < funcs.length; i++){ 12 console.log(funcs[i]()); 13 }
一般來說,以為輸出 0~9 ,但事實上是輸出10個10。
需要註意的點就是,方法帶()才是執行這個方法,而諸如 var abc = function(){ },只能說將這個方法定義並且賦值給abc,並沒有執行這個方法。
簡單來說:單純的一句 var f = function() { alert(‘lalala‘); }; 是不會彈窗的,後面接一句 f(); 才會執行方法內部的代碼,才會彈窗。
以上代碼的解釋:
1 function createFunctions(){ 2 var result = new Array(); 3 for (var i=0; i < 10; i++){ 4 result[i] = function(){ 5 return i; 6 }; 7 } 8 return result; 9 } 10 var funcs = createFunctions(); //執行了一次createFunctions() 11 for (var i=0; i < funcs.length; i++){ 12 console.log(funcs[i]()); //createFunctions的返回值是result,所以funcs[i]() 執行的是 result[i] 的方法:return i; 13 }
執行流程:
1 var result =[], i; 2 result[0] = function(){ return i; }; //沒執行函數,函數內部不變,不能將函數內的i替換!這是在將createFunction()賦值給funcs時的第一次執行這個方法 3 result[1] = function(){ return i; }; //沒執行函數,函數內部不變,不能將函數內的i替換! 4 ... 5 result[9] = function(){ return i; }; //沒執行函數,函數內部不變,不能將函數內的i替換! 6 i = 10; //此時的i = 10; 7 funcs = result; //因為createFuntions()的返回值是result 8 result = null; 9 10 console.log(i); // funcs[0]()就是執行 return i 語句,就是返回10 11 console.log(i); // funcs[1]()就是執行 return i 語句,就是返回10 12 ... 13 console.log(i); // funcs[9]()就是執行 return i 語句,就是返回10
因為正在引用 i ,所以 i 的值是10,也就是 return i ; 的值一直是return 10 。 傳遞到執行 funcs[i]() 方法裏面。
funcs[0]()就是執行 return i 語句,就是返回10
funcs[1]()就是執行 return i 語句,就是返回10
funcs[9]()就是執行 return i 語句,就是返回10
閉包就是一個函數引用另外一個函數的變量,因為變量被引用著所以不會被回收,因此可以用來封裝一個私有變量。這是優點也是缺點,不必要的閉包只會徒增內存消耗!另外使用閉包也要註意變量的值是否符合你的要求,因為他就像一個靜態私有變量一樣。閉包通常會跟很多東西混搭起來,接觸多了才能加深理解,這裏只是開個頭說說基礎性的東西。
javascript閉包問題