了解闭包
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);
}
}
});
}
这样就能达到我们想要的效果了。
以上看法仅属于个人观点,如有不正之处,望各位大大海涵,并私信错误之处。