最近在看JavaScript,看到物件導向部分的適合,一個名詞出現在我的面前,把我著實迷糊了一點時間,它的名字就是閉包。
首先說一下他的官方語言:閉包是一個擁有許多變數和綁定了這些變數的環境的運算式(通常是一個函數),因而這些變數也是該運算式的一部分。反正我看這個是不太看的明白的,就好像你對一個完全不懂數學的人,用集合的方式和他說三範式他也會不懂一樣,很苦澀,而且也很難想象。
我查了一下,閉包的應用大概有兩點:
1、保護函數內的變數安全。
2、在記憶體中維持一個變數.
下面,先看一下怎樣就算建立了一個閉包:
function a(){var i=0;function b(){alert(++i);}return b;}var c=a();c();
這段代碼的特點是:i)函數b潛逃在a的內部 ii)函數a返回函數b
關於特點i很容易理解,那麼特點ii呢?個人理解:a不必非要返回函數b,只要在函數a外調用函數b即可。
至此,不得不看一下下面這個經典的例子:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>閉包測試</title><script language="javascript" type="text/javascript">function newInit(){for(var i=1;i<=3;i++){var anchor=document.getElementById("anchor"+i);anchor.onclick=function(){alert(i);}}}window.onload=newInit;</script></head><body><a id="anchor1" href="#">abc</a><br /><a id="anchor2" href="#">abc</a><br /><a id="anchor3" href="#">abc</a><br /></body></html>
有三個超連結,上面的js目標是想給著三個超連結的onclick都添加一個函數,使其返回是第幾個超連結。大家可以看一下,著其實就是一個閉包。至於為什麼,自己和上面的例子對比,如果你對比不來,那麼就繼續看。
下面我只說問題:
i)雖然上面的實現了閉包,使得在click事件發生時,還可以找到i,但是此時i已經時過境遷,函數的發生時
在onload事件裡面發生的,當clcik時,此事件早已發生完了,那麼發生時去找尋i,此時找到的i已經等於 4了。
ii)而我們需要的是什麼呢?需要的是在對onclick事件進行編寫的適合,將此時的i的值記下來,這不是與
閉包的功能不謀而合嘛。所以,此例子還需要再套一個閉包。
進而有了改編的代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>閉包測試</title><script language="javascript" type="text/javascript">function newInit(){for(var i=1;i<=3;i++){var anchor=document.getElementById("anchor"+i);registerListener(anchor,i);}}function registerListener(anchor,i){anchor.onclick=function(){alert(i);}}window.onload=newInit;</script></head><body><a id="anchor1" href="#">abc</a><br /><a id="anchor2" href="#">abc</a><br /><a id="anchor3" href="#">abc</a><br /></body></html>
不知道大家到底有沒有發現裡面的閉包,下面我給大家點一下。newInit其實相當於a,registerListener相當於b,onload相當於c,二在registerListener這個函數中,registerListener相當於a,onclick相當於b,在newInit中的registerListener調用又相當於了c。說的有點繞,關於閉包,還是需要大家用一點心情慢慢理解一下的。
相信看了我這篇文章後,你對閉包應該會有一個表面的認識了,再深層的,就需要去瞭解他的回收機制了,這篇文章適合剛剛接觸JavaScript的人看,同時歡迎大蝦指教。