閉包
- 閉包的定義: 當一個內部函數被其外部函數之外的變量引用時,就形成了一個閉包。
// 以下面的代碼爲例:即是外部的變量c引用了a內部的b函數,這樣形成了一個簡單的閉包
function A(){
function B(){
console.log('Hello Closure!');
}
return B;
}
var C = A();
C();// Hello Closure!
閉包的用途
- 先看看js的GC制度:在 Javascript 中,如果一個對象不再被引用,那麼這個對象就會被 GC 回收,否則這個對象一直會保存在內存中。
- 看一個利用閉包的優雅小例子,使用某個變量使其一直保存在內存中且不污染全局變量:
// count 是函數A 中的一個變量,它的值在函數B 中被改變,函數 B 每執行一次,count 的值就在原來的基礎上累加 1 。因此,函數A中的 count 變量會一直保存在內存中
function A() {
var count = 0;
function B() {
count ++;
console.log(count);
}
return B; // 不要忘記!!!
}
var C = A();
C();// 1
C();// 2
C();// 3
// 這種方法下巧妙的完成了一個累加器
閉包高級寫法
- 在實際應用中,閉包一般與匿名函數一起使用
// 既然上邊一段代碼可以看出a函數僅僅是爲了讓count變量在內存中一直存在而已,因此我們可以將這個函數變成匿名函數並直接執行
(function (document) {
var viewport;
var obj = {
init: function(id) {
viewport = document.querySelector('#' + id);
},
addChild: function(child) {
viewport.appendChild(child);
},
removeChild: function(child) {
viewport.removeChild(child);
}
}
window.jView = obj;
})(document);
- 這裏邊用到了匿名函數:
(function(3){})(4)
- 與普通函數區別除了沒有名字外是它有最大的外括號,相當於定義了這個函數,最後的括號相當於是執行這個匿名函數,括號3,4分別對應普通函數的形參和實參,根據需要傳入即可。
上邊一段代碼可變成:
var f = function(document) {
var viewport;
var obj = {
init: function(id) {
viewport = document.querySelector('#' + id);
},
addChild: function(child) {
viewport.appendChild(child);
},
removeChild: function(child) {
viewport.removeChild(child);
}
}
window.jView = obj;
};
f(document);
注意不能過度使用閉包,,因爲它對內存的花銷較大