閉包,首先搞清楚兩件事:1、變量的作用域 ?2、垃圾回收機制
一:變量的作用域
1、變量的作用域無非就是兩種:全局變量和局部變量。
例子1:
var c = 0 ;?
function m1(){
?console.log(c);
}
m1()?;?
例子2:
function m2(){
? var c = 0 ;
}
m2();?
console.log(c);?
例子3:
function m3(){
? ?c = 0;
}
m3();
console.log(c);
2、如何從外部讀取局部變量?
出于種種原因,我們有時候需要得到函數內的局部變量。但是,前面已經說過了,正常情況下,這是辦不到的,只有通過變通方法才能實現。
那就是在函數的內部,再定義一個函數。
function f1(){
?var ?n=999;
function f2(){
? ?console.log(n)
}
return f2;
}
var ?newFn =?f1();
newFn(); ?
在上面的代碼中,函數f2就被包括在函數f1內部,這時f1內部的所有局部變量,對f2都是可見的。但是反過來就不行,f2內部的局部變量,對f1 就是不可見的。這就是Javascript語言特有的“鏈式作用域”結構,
子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。
3、什么是閉包?
? ?官方的解釋是:閉包是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
例子:
function a(){
var i = 0;
function b(){alert(++i);}
return b;
}
var c = a();
c();
這樣在執行完var c=a()后,變量c實際上是指向了函數b,再執行c()后就會彈出一個窗口顯示i的值(第一次為1)。這段代碼其實就創建了一個閉包,為什么?因為函數a外的變量c引用了函數a內的函數b,就是說:
當函數a的內部函數b被函數a外的一個變量引用的時候,就創建了一個閉包。
簡單來說:閉包就是能夠讀取其他函數內部變量的函數。(個人理解~);Funciotn that is return function
四、閉包的用途
閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。
二:垃圾回收機制
在Javascript中,如果一個對象不再被引用,那么這個對象就會被GC(garbage collection)回收。如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。
JavaScript的解釋器可以檢測到何時程序不再使用一個對象了,當他確定了一個對象是無用的時候,他就知道不再需要這個對象,可以把它所占用的內存釋放掉了;