一個常見的閉包函式的分析

juzipchy發表於2017-02-15

先看個程式碼:

    //糟糕的例子
    //構造一個函式,用錯誤的方式給一個陣列中的節點設定事件處理程式
    //當點選一個節點時,按照預期,應該彈出一個對話方塊顯示節點的序號
    //但它總是會顯示節點的數目
    var add_the_handlers=function(nodes){
        var i;
        for(var i=0;i<nodes.length;i++){
            nodes[i].onclick=function(e){
                alert(i);
            };
        }
    };

add_the_handlers函式的本意是想傳遞給每個事件處理器一個唯一值(i),但它未能達到目的,因為事件處理器函式繫結了變數i本身,而不是函式在構造時的變數i的值。

for迴圈有一個自己的小小作用域,每執行一次,只是將function賦給onclick事件,和函式內的內容無多大關係。最後點選時觸發執行,此時的i已經為4,所以全部為4.該處重點理解 將函式當成一個資料型別,每迴圈一次相當於賦與函式一次,並未執行

    //改良後的例子
    //構造一個函式,用正確的方式給一個陣列中的節點設定事件處理程式
    //點選一個節點時,彈出一個對話方塊顯示節點的序號

    var add_the_handlers=function(nodes){
        var helper=function(i){
            return function(e){
                alert(i);
            };
        };
        var i;
        for(var i=0;i<nodes.length;i++){
            nodes[i].onclick=helper(i);
        }
    };

總結:
避免在迴圈中建立函式,它可能只會帶來無謂的計算,還會引起混淆。
我們可以在迴圈之外創造一個輔助函式,讓這個輔助函式再返回一個繫結了當前i值的函式。

相關文章