javascript - 初學閉包,不太明白,求大神指教
大家讲道理
大家讲道理 2017-06-26 10:58:00
0
7
685
function box() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = function () {
            return i;
        }
    }
    return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
    alert(b[i]);
}     

當box()執行完之後,為什麼arr[0]到arr[4]裡面的值都是function () { return i;}
為什麼不依序是:function () {return 0;} ,function () {return 1;}。 。 。

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回覆(7)
学习ing

因為閉包只能取得包含函數中任何變量的最後一個值,在這裡指的就是i這個變量,box()函數執行後返回的是一個函數數組,數組中的每一個i引用的都是同一個變數i,注意box()回傳的是一個函數!所以裡面的{return i}這只是函數內的一個聲明,還沒有執行呀,所以當然保持{return i}不變。因為引用的是同一個外部i,所以當box()函數返回後,外部變數i的值是5,此時每一個return中都引用著保存變數i的同一個變數對象,所以如果最後執行了內部的arr[]中的函數,最後每個函數內部的i的值都是5.

//执行内部返回的arr中的函数,当然box()[1]()、box()[2]()、box()[3]()...都返回5;
    function box() {
        var arr = [];
        for (var i = 0; i < 5; i++) {
             arr[i] = function () {
                return i;
            }
        }
        return arr;
    } 
    box()[1](); //执行后返回5

//不执行内部函数,仅仅是box()的话,当然只返回一个function咯
    function box() {
        var arr = [];
        for (var i = 0; i < 5; i++) {
             arr[i] = function () {
                return i;
            }
        }
        return arr;
    } 
    box(); //[function, function, function, function, function]
伊谢尔伦

因為關聯到閉包的作用域鍊是"活動的". 並且他們共享變數i , 並不是對每個綁定的變數的值賦值自己單獨的一份. 他們只是引用i,並不會保存i 每個階段的值.

參考書籍: JavaScript 權威指南 8.6 小節.

淡淡烟草味

雷雷

世界只因有你

雷雷

阿神

範例中for循環裡的function只是賦值,並沒有執行,所以當數組中函數執行時才去獲取i的值,這時候i只有循環結束的值,樓上沒有用到閉包,只是用一個立即執行的匿名函數得到了每個循環的i的值;
方法:1.用ES6 let取代var
function box() {

    var arr = [];
    for (let i = 0; i < 5; i++) {
        arr[i] = function () {
            return i;
        }
    }
    return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
    alert(b[i]());
}

2.採用閉包
function box() {

    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = function (x) {
            return function(){
                return x;
            };
        }(i);
    }
    return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
    alert(b[i]());
}
我想大声告诉你

。 「閉包」 一詞來自以下兩者的結合:要執行的程式碼區塊(由於自由變數被包含在程式碼區塊中,這些自由變數以及它們引用的物件沒有被釋放)和為自由變數提供綁定的運算環境(作用域) ---百度百科
意思是

function () {
                return i;
            }

這個就是一個程式碼塊,作用只是他引用了i,這樣持有i就會導致i不會被釋放掉,我們保存的只是這個程式碼塊,這個程式碼塊不運行之前,他根本不知道i是什麼東西,就有他運行的時候,他才會去找i,所以你可以把你的arr都輸出一下,應該輸出的全是5

我想大声告诉你
// arr的元素均是下面这个函数 
function(){
    return i; 
}

呼叫的時候才計算 i 是什麼。

而在呼叫這些函數的時候,for 已經結束,因此取 i 的時候值是 5

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板