您好,登錄后才能下訂單哦!
本文實例講述了JS閉包。分享給大家供大家參考,具體如下:
之前花了很多時間看書上對閉包的介紹,也看了很多人的寫的關于閉包的博客,然后我就以為自己懂了。
結果,下午在一個QQ群里,有人問了這道經典的閉包問題,如下圖:
我告訴他去看書上的閉包介紹。告訴他之后,我想我自己要不也寫一下,反正花不了多少時間,結果花了好久怎么寫也不對..............
后來看了看書上的,然后自己總結了下,覺得這次應該懂了。下次還不理解我就可以去跳樓了............
-----------------------------------分割線-----------------------------------分割線--------------------------
首先我們來了解幾個概念:
立即執行函數:形如 (function(){})();
的一類函數;
閉包:閉包是指有權訪問另一函數作用域中的變量的函數。
作用域鏈:當代碼執行的時候,會創建變量對象的一個作用域鏈....(具體百度)
我們再來看這個問題,我重新寫了一個,源碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>閉包經典例子詳解——huansky</title> </head> <body> <div id="ttt"> <p >000000000000000000</p> <br> <p >111111111111111111</p> <br> <p >222222222222222222</p> </div> </body> <script> var dom=document.getElementsByTagName("p"); for(var i=0;i<dom.length;i++){ dom[i].onclick=function(){ console.log(i);//3 }; } </script> </html>
首先,代碼中的匿名函數沒有變量 i,所以它必須向上查找,在全局環境中找到了 i。
當for
循環運行后,全局變量中的 i 變成了3。此時當你點擊文字的時候,會調用其綁定的函數,而該函數運行的時候,發現自己沒有 i,就會取得全局環境中的 i。
所以,最后的結果是,不管你點擊那段文字,最后結果都是3。
PS:感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼,看看運行效果。
那怎么辦呢?你可以用立即執行函數,看代碼:
for(var i=0;i<dom.length;i++){ dom[i].onclick=function(i){ return function( ){ console.log(i); }; }(i); }
我們把參數 i 作為傳給立即執行函數,這樣,i 的值就傳給了立即執行函數的局部變量 i 了。立即執行函數會直接執行,但是其活動不會銷毀,因為里面有個匿名函數。執行后局部變量 i 與全局變量 i 聯系就切斷了,也就是執行的時候,傳進去的變量 i 是多少,立即執行函數的局部變量 i 就是多少,并且該局部變量 i 仍然沒有消失,因為匿名函數的存在。
這時候,return
中的匿名函數的作用域鏈中會有兩個變量 i。當點擊文本的時候,它向上搜索 i 的時候,它找到立即執行函數的局部變量 i ,就停止向上查找了,因此最后的結果就不會是全局變量 i 的值3了。
有一個方法可以檢驗你們有沒有真的理解上面所說的,看上面的變體,代碼:
for(var i=0;i<dom.length;i++){ dom[i].onclick=function(t){ return function( ){ console.log(t);//1 console.log(i);//3 }; }(i); }
其實return中的匿名函數中的 t 就是立即執行函數的局部變量 i,而 i 就是 指全局變量 i,因為立即執行函數中沒有變量i,只能繼續向上搜索,然后就找到全局變量的 i 了。
如果看到這里,你還沒有理解,有兩個原因:一個原因是我表達的不夠好,另一個原因是你沒有完全理解前面提到的這些概念,還要繼續看書。
更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數學運算用法總結》
希望本文所述對大家JavaScript程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。