透过【百度地图API】分析双闭包问题
摘要:
有位API爱好者问到,昨天的教程里为什么不使用for循环?他使用for循环后,也发现代码无效。这是什么原因?
-------------------------------------------------------------------------------------------------------
我们先来看看他的问题:
寒山 2011-9-8 23:37:36
方法一
for(var i=0; i<marker.length; i++){
marker[i].addEventListener("mouseover", function(){
this.openInfoWindow(infoWindow[i]); });
}
方法二
marker[2].addEventListener("mouseover", function(){
this.openInfoWindow(infoWindow[2]);});
marker[1].addEventListener("mouseover", function(){
this.openInfoWindow(infoWindow[1]);});
用户提问:
这两种方式有什么区别吗? 为什么前面用循环的不可以,后面的就可以..
-------------------------------------------------------------------------------------------------------
解答:
首先,我们要知道,this.openInfoWindow(infoWindow[i])中的i最后的值是marker.length-1
数组的下标是从0开始的,0,1,2……(N-1)
以闭包方式解决的原因如下:
i是外层的变量,是callback上层作用域的,callback执行的时候,for已经循环完了。创建一个闭包,相当于在内存中创建一个地方,专门存储起来。
所以,可以用双闭包的方式解决:
for(var i=0;i<marker.length;++i){
(function(x){
marker[x].addEventListner("mouseover",function(){
this.openInfoWindow(infoWindow[x]);
});
})(i);
}
双闭包的代码会创建marker.length*2个匿名函数。下面这段代码只有一个_openInfoWindow。
所以,我们换一种方式:
function _openInfoWindow(){
this.openInfoWindow(this._infoWindow);}
for(var i=0;i<markers.length;++i){
marker[i]._infoWindow = infoWindow[i];
marker[i].addEventListner("mouseover",_openInfoWindow);
}
-------------------------------------------------
结论:
能尽量用别的方式,就不要用闭包解决问题。否则会影响到性能。