當function裏嵌套function時,內部的function能夠訪問外部function裏的變量。數組
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(10);
}
foo(2)閉包
無論執行多少次,都會alert 16,由於bar能訪問foo的參數x,也能訪問foo的變量tmp。函數
但,這還不是閉包。當你return的是內部function時,就是一個閉包。內部function會close-over外部function的變量直到內部function結束。spa
function foo(x) {作用域
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 如今是一個閉包
bar(10);io
上面的腳本最終也會alert 16,由於雖然bar不直接處於foo的內部做用域,但bar仍是能訪問x和tmp。function
可是,因爲tmp仍存在於bar閉包的內部,因此它仍是會自加1,並且你每次調用bar時它都會自加1.變量
(考慮到六歲這個限制:咱們其實能夠創建不止一個閉包方法,好比return它們的數組,也能夠把它們設置爲全局變量。它們全都指向相同的x和相同的tmp,而不是各自有一份副本。)object
注:如今來整點兒七歲的內容。引用
上面的x是一個字面值(值傳遞),和JS裏其餘的字面值同樣,當調用foo時,實參x的值被複制了一份,複製的那一份做爲了foo的參數x。
那麼問題來了,JS裏處理object時是用到引用傳遞的,那麼,你調用foo時傳遞一個object,foo函數return的閉包也會引用最初那個object!
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar 如今是一個引用了age的閉包
bar(10);
不出咱們意料,每次運行bar(10),x.memb都會自加1。但須要注意的是x每次都指向同一個object變量——age,運行兩次bar(10)後,age.memb會變成2.