先看个代码:
//糟糕的例子
//构造一个函数,用错误的方式给一个数组中的节点设置事件处理程序
//当点击一个节点时,按照预期,应该弹出一个对话框显示节点的序号
//但它总是会显示节点的数目
var add_the_handlers=function(nodes){
var i;
for(var i=0;i<nodes.length;i++){
nodes[i].onclick=function(e){
alert(i);
};
}
};
add_the_handlers函数的本意是想传递给每个事件处理器一个唯一值(i),但它未能达到目的,因为事件处理器函数绑定了变量i本身,而不是函数在构造时的变量i的值。
for循环有一个自己的小小作用域,每执行一次,只是将function赋给onclick事件,和函数内的内容无多大关系。最后点击时触发执行,此时的i已经为4,所以全部为4.该处重点理解 将函数当成一个数据类型,每循环一次相当于赋与函数一次,并未执行
//改良后的例子
//构造一个函数,用正确的方式给一个数组中的节点设置事件处理程序
//点击一个节点时,弹出一个对话框显示节点的序号
var add_the_handlers=function(nodes){
var helper=function(i){
return function(e){
alert(i);
};
};
var i;
for(var i=0;i<nodes.length;i++){
nodes[i].onclick=helper(i);
}
};
总结:
避免在循环中创建函数,它可能只会带来无谓的计算,还会引起混淆。
我们可以在循环之外创造一个辅助函数,让这个辅助函数再返回一个绑定了当前i值的函数。