下面的程序想实现功能:创建 10 个 li 节点,添加到 id="ulist" 的 ul 中,当鼠标经过每个 li 节点时,就在显示区添加一句 pass + (li 节点的标号 ) 。
<ul id="ulist"></ul>
<div id="show"></div>
<script>
dojo.addOnLoad(function() {
for(var i=0;i<10;i++){
var a = dojo.doc.createElement("li");
a.innerHTML = "item " + i;
dojo.connect(a,"mouseover", function(){
show.innerHTML = show.innerHTML + "<br/> pass " + i;
} );
ulist.appendChild(a);
}
});
</script>
上述代码并没有达到要求,鼠标经过任一个 li 节点时,显示区就多一句 “pass 10” 。
问题出在给 mouseover 绑定的响应函数上,当鼠标经过任一个 li 节点时,就去执行代码中的匿名函数
function(){
show.innerHTML = show.innerHTML + "<br/> pass " + i;
}
i 源于该匿名函数定义时所在的环境,在该环境中 i 的值随着 for 循环从 0 增长到 10 ;到后来匿名响应函数执行时, i 的值是 10 ,而不是像期望的那样去反映 li 的标号。
修正方法:给每个 li 绑定一个新建的函数,新建的函数中使用的变量不依赖 i 。将代码中的蓝色部分改为
function getFun(k){
return function(){ show.innerHTML = show.innerHTML + "<br/> pass " + k;}
}
dojo.connect(a,"mouseover", getFun(i));
或者合并为
dojo.connect(a,"mouseover", (function(k){
return function(){ show.innerHTML = show.innerHTML + "<br/> pass " + k;}
})(i));
都是可行的。