在最近在js的學習中,我接觸到了js之中一個比較難的模塊:閉包。但是這個模塊卻可以在js程序中發揮巨大的作用,本文以學習過程中的一個經典實例作為例子講述對閉包作用的收獲。
在下列的代碼裡,我想實現的是,當點擊 <ol>
中各個<li>
時,頁面會彈窗顯示四個不同的數字
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<ol>
<li>第一項</li>
<li>第二項</li>
<li>第三項</li>
<li>第四項</li>
</ol>
<script type="text/javascript">window.onload=function () {var lis =document.getElementsByTagName('li');for (var i =0; i <lis.length; i++) {
lis[i].onclick=function () {alert(i);};}}</script>
</body>
</html>
但是實際的結果是,在不同的<li>
上點擊時,彈出的窗口顯示的數字都是4(黑人問號??)
經過查閱資料以及課程老師的講解,我明白了這個問題出現的原因:在這個例子裡面,alert(i)
的this
是window
,(原因是,alert對應的的作用域是對應的<li>
,而它的方法裡面alert的作用域是window
) 所以在鼠標點擊這個事件調用函數之前,早在頁面加載的過程中,for循環已經完成,得到的i都是值為4
所以為了使得原來的需求能夠實現,我們可以使用函數閉包,將變量i加入到事件處理器onclick
的函數閉包之中,實現如下:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<ol>
<li>第一項</li>
<li>第二項</li>
<li>第三項</li>
<li>第四項</li>
</ol>
<script type="text/javascript">window.onload=function () {var lis =document.getElementsByTagName('li');for (var i =0; i <lis.length; i++) {
lis[i].onclick=function (i) {returnfunction () {alert(i);}} (i);//利用IIFE實現函數閉包,將i作為參數傳入即可}}</script>
</body>
</html>
有什麼不嚴謹的地方還望各位看官指出!