一、什麼是閉包
距離上一次更新有一段時間了,過年你懂得,接下來就談談JavaScript的高級用法——閉包。js的閉包其實不是什麼難懂的高深的概念,只是有些書籍當中介紹的不夠易懂或者說舉得例子不太恰當,現在我們就通過簡單的例子來理解“閉包”。作爲程序員,也許一段針對的代碼,比那些文字描述更能說明問題,用代碼說話,眼見爲實。
好了,先看下面的一段代碼:
function t1(){
var age = 20;
function t2(){
alert(age);
}
return t2;
}
var age = 100;
var temp = t1();
temp();//20
爲了突出 執行效果,在t1函數外層也定義了一個age=100的變量,執行完 var temp = t1(); 後,將函數t2賦予了temp,這樣temp其實就是t2函數的引用,緊接着執行temp,輸出結果竟然是20,毫無疑問,變量age是在t1函數的作用域下的,你已經看到JavaScript語言與其他語言不同的地方。
在大部分語言中,如java,函數t1內的局部變量會隨着函數t1執行結束而銷燬,但是在js中,變量age=20卻被t2捕抓,即使是t1函數執行結束後,依然可以通過t2訪問到age
這種情況,即返回的t2函數不是孤立的,甚至把周圍的變量環境,形成了一個‘封閉包’,一起返回,所以叫‘閉包’
二、閉包的應用
JavaScript既然有閉包的實現,那麼JavaScript的閉包是怎麼使用的或應用在哪種情況下呢?通過上面的例子已經看到,函數t1內部的age變量只能通過返回的t2函數訪問,那麼age是不是相當於java的private私有變量呢,哈哈,這個在下一篇會講到,而且將通過“閉包”將屬性封裝在內部,做成接口,別人也就看不見,也不會污染到其他的變量,想想是不是呢。
講那麼多,我們就通過一個實際的例子看看:
要求:實現一個計數器,每次調用某函數,使計時器的值加1
1、閉包實現
function counter(){
var i = 0;//但counter執行完畢後,除了返回的inc函數,其他函數訪問不了變量i
var inc = function(){
return ++i;
}
return inc;
}
var c = counter();
alert(c());
alert(c());
alert(c());
2、可以結合“匿名”函數,進行簡化
var counter = (function(){
var i = 0;
return function(){
return ++i;
}
})();
alert(counter());
alert(counter());
alert(counter());
相信你已經看到了閉包的好處,但是請不到胡亂使用閉包,因爲在IE瀏覽器下是使用“計數”的方式跟蹤對象來進行垃圾回收的,由於閉包的特新,不會釋放局部變量,如果造成過多的循環引用,將會引起“內存泄露”。