閉包循環問題--for循環只顯示最后一個i的值


<div>DIV 0</div>
<div>DIV 1</div>
<script>
    var divs = document.getElementsByTagName("div");
    for (var i = 0; i < divs.length; i++) {
        divs[i].addEventListener("click",function(){
            alert("divs #" +i+ "was clicked.");
        },false);
    }
</script>

這段代碼主要用來操作2個div,哪個div被點,然后彈出框提示第i個div被點;

問題是:無論點哪個div,彈出框提示的始終都是第二個div被點了。

以上代碼中遇到了一個使用閉包和循環時常見的問題,也就是說函數綁定之后,閉包抓取的變量被更新了。這意味着,每一個綁定的函數處理程序都會一直顯示i最后的值;

 

處理代碼如下

<div>DIV 0</div>
<div>DIV 1</div>
<script>
    var divs = document.getElementsByTagName("div");
    for (var i = 0; i < divs.length; i++) (function(n){
        divs[n].addEventListener("click",function(){
            alert("div #" +n+ "was clicked.");
        },false);
    })(i);
</script>
<div>DIV 0</div>
<div>DIV 1</div>
<script>
    var divs = document.getElementsByTagName("div");
    for (var i = 0; i < divs.length; i++) (function(n){
        divs[n].addEventListener("click",function(){
            alert("div #" +n+ "was clicked.");
        },false);
    })(i);
</script>

加入一個即時函數,注意 for (var i = 0; i < divs.length; i++) 后面的代碼的寫法(即時函數的寫法)。

首先解釋一下即時執行函數;

(function(){})();

簡寫(......)();

第一對括號內是一個函數體(表達式),這對括號僅用於划定表達式的范圍;
第二對括號內是一個操作符,表示立即執行上面的表達式;而第二對括號內的值(如果有的話),就是執行上面表達式所需要的參數(也分實參、形參)

fo循環里,i的值變化,n的值也會跟着變化(當然要變化啦,i是實參,n是形參)

通過在for循環內加入即時函數,我們可以將正確的值傳遞給即時函數,進而讓處理程序也得到正確的值。這意味着,在for循環每次迭代的作用域中,i變量都會重新定義,從而給click處理程序的閉包傳入我們期望的值。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM