閉包 什么是閉包?JS最重要的部分之一就是閉包,最近又回過來復習基礎的時候看見閉包了,以前也不是那么理解這東西,如果是自學的小白JS這部分看起來真的太費勁了,看的讓人懷疑人生,看的懷疑自己是不是只有編程細菌。。。。好了廢話不多說了,再細講閉包之前呢,咋們先看個例子!??! 例:給三個button分別添加事件,點擊的時候顯示出點擊的是第幾個button???
乍一看是不是覺得很簡單?那就開始寫吧

思路是這樣的沒錯吧,想要讓每個按鈕都有事件用for循環(huán)給每個button添加事件然后保存,可是事與愿違啊,真的是這樣的嗎??? 

這是最后的測試結果,第三個我沒點擊不用想了也是這個結果,驚大呆,這是為什么呢??? 其實吧這個時候就構成了閉包,首先分析一下為什么點擊每個按鈕都顯示的是點擊了第三個按鈕呢?這是因為每循環(huán)一次給btnList添加一個function,最后btnList是這樣的 btnList[function(){},function(){},function(){}],里面有3個function,在for里面聲明了function,但是它沒有執(zhí)行啊是不是?真正執(zhí)行的時候是當你點擊button的時候才執(zhí)行這個函數(shù)啊,當你的行的時候bt已經(jīng)變成3了,所以每觸發(fā)一次事件都訪問的是等于3的bt,所以每次訪問都是3,先將閉包然后再用閉包來解這道題?。?/p> 閉包通俗點來說就是在外面能訪問到局部變量,想想該怎么訪問呢?
結果輸出就是0;而其中的child就是閉包,通常的閉包就長這樣。。。在一個函數(shù)的內部再定義一個函數(shù)十有八九會產(chǎn)生閉包,不要把閉包想的那么復雜,說了半天就是讓在函數(shù)外面訪問函數(shù)內部的變量,它算是一座橋吧?。?! 行,現(xiàn)在可以解決那個問題了,那就是把里面的onclick函數(shù)放在立即執(zhí)行函數(shù)里,???什么是立即執(zhí)行函數(shù)???從字面意思理解就是馬上執(zhí)行,完了就完了。。。 var btnList=document.getElementsByTagName("button"); for(var bt = 0;bt < btnList.length;bt ++){ btnList[bt1].οnclick=function(){ alert("您點擊了第"+(bt1+1)+"個按鈕");
當當當,就是它,把onclick這個函數(shù)放進立即執(zhí)行函數(shù)里面就可以了,為什么可以呢,解釋一下。。。因為當它執(zhí)行for循環(huán)的時候每循環(huán)一次把bt送給bt1然后保留,執(zhí)行完這個歌立即執(zhí)行函數(shù)后銷毀,再次執(zhí)行的時候又是下一個值,所以最后拿出來的是你每循環(huán)一次的那個值而不是前面所說的執(zhí)行到最后的那個值,執(zhí)行函數(shù)是個好東西啊,它可以避免變量名的沖突,在一個立即執(zhí)行函數(shù)里隨便定義變量,只要出了這個作用域就沒這個變量了,是不是美滋滋!??!補充一點,如果學習過ES6的話那個東西還可以那樣寫,不用閉包,那就是把for循環(huán)中的 var bt=0;中的var改成ES6中的 let 其實和立即執(zhí)行函數(shù)差不多,都是作用域的問題?。。?/p> 說到這呢,大概對它有一定的了解了,可是知道了閉包什么時候用呢???只知道它是干嘛的不知道怎么用那不是白瞎嗎?其實我覺得吧什么時候用的多呢?就是在模塊化開發(fā)的時候,假如開發(fā)的時候需要有一個專門計算的模塊,這個時候總不能使用全局變量吧,假如在外面調用這個模塊,它直接返回計算值,這個時候就只能用閉包了!
不過吧,前面所說的那個return child()這個東西吧即在father的內部又在全局里面,所以啊它的那個變量會一直存在而不會被銷毀,好多人都說閉包會引起內存的泄漏,但是吧,我覺得有時候有些開發(fā)必須得用閉包,是會引起內存泄漏,但是合理的利用就不會那么嚴重!下面談談內存泄漏吧 內存泄漏 就這個名詞以前我第一次看的時候硬是沒想通人家的內存泄漏到底是什么鬼?漏了?還是怎么回事???最近復習的時候我又好好的研究了一下這個名詞,說了半天就是可用的內存泄露了,能用的就少了,是可用的泄露了。。。。大概就這么個意思吧,說起內存泄漏又會牽扯到這個垃圾回收的問題,過兩天我總結一下然后寫一份自己對垃圾回收的博客,今天就簡單的說說內存泄漏怎么解決吧,就是把那些不需要的變量,但是垃圾回收又收不走的的那些賦值為null,然后讓垃圾回收收走?。。?/p>
|