js初學者常遇到的一個for循環中onclick問題

首先看一段代碼:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <button>0</button>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <script> 
        var btn=document.getElementsByTagName('button');
        for(var i=0;i<btn.length;i++){ 
            btn[i].οnclick=function(){ 
                console.log(i);
            }
        }
    </script>
</body>
</html>

然後運行一下,當時作爲一名天真的js初學者理所當然的認爲分別點擊不同的額按鈕,會分別的打印出0、1、2、3、4,然而事與願爲,現實和理想總是存在差距,點擊不同的按鈕,打印卻都是5,百思不得其解,不科學啊!
最後百度了一番才恍然大悟,原來console.log(i)裏的i在循環完成的時候被賦值成了5,而每個按鈕的onclick都被賦值了同一個function,也就是說每個function裏的i指的是同一個i,i=5,自然每個點擊都會打印出5,那麼該怎麼解決呢?!
再看接下來這段代碼:

    <script> 
        var btn=document.getElementsByTagName('button');
        for(var i=0;i<btn.length;i++){ 
            (function(i){ //這個是function裏i,即function的形參,也可以換成j,換成什麼變量名都無所謂
                btn[i].οnclick=function(){ 
                    console.log(i);
                }
            })(i);//這是循環中的i,被作爲參數傳入
        }
    </script>

再運行這段代碼,就可以得到你想要的效果,但是是爲什麼呢?
知道了原因就好辦了,利用閉包把每個function裏的i都變成不同的i就行了,當時作爲一名初學者還不懂閉包,也是後來才理解的。
循環中的function自調用,將循環中的i作爲參數傳入function中,此時,function中的i已經不是循環中的i了(這裏有點繞,其實形參i,即function裏的i換成什麼變量名都行),而是在內存中開闢了一個內存空間存儲了作爲參數傳進來的i的值,這樣function中的就不會隨着循環中的i的值的改變而改變了,就可以打印出你要的結果了。

怎麼樣?是不是很坑爹,這是一個很常見的問題,還望js的初學者們好好體會,我當時也是矇蔽了好久!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章