js開發中閉包問題

瞭解閉包

js閉包問題說到底就是js的作用域問題,而作用域在js中也就是局部變量和全部變量。局部變量是指只能在本變量聲明的函數內部調用。全局變量時整個代碼中都可以調用的變量。

eg1: 

var aa = 10;

function fun(){

var bb = 20;

console(aa);

console(bb);

}

fun();

上段代碼中,aa即爲全局變量,bb爲局部變量。


什麼是閉包?

閉包就是能夠讀取其他函數內部變量的函數。由於在javascript中,只有函數內部的子函數才能讀取局部變量,所以說,閉包可以簡單理解成“定義在一個函數內部的函數“。

所以,在本質上,閉包是將函數內部和函數外部連接起來的橋樑。

我遇到的閉包問題

先看這樣一段代碼。

for (var ii = 0; ii < 5; ii++) {
    items[ii].addTouchEventListener(function (sender, eventType) {
        if (eventType === ccui.Widget.TOUCH_ENDED) {
            if (self.curState === 0) {
                self.curState = 1;
                self.back_btn.setVisible(true);
                self.return_btn.setVisible(false);
                self.record_scroll.setVisible(false);
                self.record_item_panel.setVisible(true);
                UICommonWidget.update_scroll_items(self.record_item_scroll, recordList[ii]["round_result"], update_item_func);
            }
        }
    });
}

當這段代碼執行完畢之後,你會發現update_scroll_items方法只調用了items最後一個元素的數據,而不是理想中調用的items0 - items4,這就是因爲update_scroll_items

函數在for循環內部的一個函數裏面,他調用的ii每次都只調用了等於4的數據,這就是因爲閉包的原因。

那麼怎麼解決這個問題呢,在JavaScript ES6 裏面有一個let申明變量關鍵字,我們只需要在for循環內部另外申明一個全局變量就可以了。修改代碼如下:

for (var ii = 0; ii < 5; ii++) {

let i = ii;
    items[i].addTouchEventListener(function (sender, eventType) {
        if (eventType === ccui.Widget.TOUCH_ENDED) {
            if (self.curState === 0) {
                self.curState = 1;
                self.back_btn.setVisible(true);
                self.return_btn.setVisible(false);
                self.record_scroll.setVisible(false);
                self.record_item_panel.setVisible(true);
                UICommonWidget.update_scroll_items(self.record_item_scroll, recordList[i]["round_result"], update_item_func);
            }
        }
    });
}

這樣就能達到我們想要的效果了。

以上看法僅屬於個人觀點,如有不正之處,望各位大大海涵,並私信錯誤之處。


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