什麼是閉包?javascript
閉包就是可以讀取其餘函數內部變量的函數。java
例如在javascript中,只有函數內部的子函數才能讀取局部變量,因此閉包能夠理解成「定義在一個函數內部的函數「。
在本質上,閉包是將函數內部和函數外部鏈接起來的橋樑。數組
代碼演示:bash
當function
裏嵌套function
時,內部的function
能夠訪問外部function
裏的變量閉包
function fn(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(2);
}
fn(1)
複製代碼
無論執行多少次,都會alert 7
,由於bar
能訪問fn
的參數x
,也能訪問fn
的變量tmp
。函數
可是,這並 不是 不是 不是 閉包ui
當你return
的是內部function
時,纔是閉包spa
內部function
會close-over
外部function
的變量直到內部function
結束。code
function fn(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = fn(1); // bar 如今是一個閉包
bar(2);
複製代碼
上面的腳本最終也會輸出alert 7
,由於雖然bar
不直接處於fn
的內部做用域,但bar
仍是能訪問x
和tmp
。生命週期
可是,因爲tmp
仍存在與bar
閉包的內部,因此它仍是會自加1,並且你每次調用bar
時它都會自加1。
其實,咱們其實能夠創建不止一個閉包方法,好比return
它們的數組,也能夠把它們設置爲全局變量。它們全都指向相同的x
和相同的tmp
,而不是各自有一份副本。
一個須要關注的點:
JS裏處理object
時是用到引用傳遞的,那麼,你調用fn
時傳遞一個object
,fn
函數return
的閉包也會引用最初那個object
?
function fn(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var tar = new Number(1);
var bar = fn(tar); // bar 如今是一個引用了tar的閉包
bar(2);
複製代碼
不出咱們意料,每次運行bar(2)
,x.memb
都會自加1。但須要注意的是x
每次都指向同一個object
變量tar
。
這樣內存泄漏有關。
有一個不用return
關鍵字的閉包例子:
function closureExample(obj, text, timedelay) {
setTimeout(function() {
document.getElementById(objID).innerHTML = text;
}, timedelay);
}
closureExample(‘myDiv’, ‘Closure is created’, 500);
複製代碼
總結:
JS裏的function
能訪問它們的:
若是在一個函數中,又嵌套了一個函數,而且裏面這個函數引用外面的函數的變量,那麼就是閉包。
閉包的特色: