为了避免下面的问题,理解内部函数能访问外部函数的实际变量而无须复制是很重要的
//糟糕的例子
//构造一个函数,用错误的方式给一个数组中的节点设置事件处理程序
//当点击一个节点时,按照预期,应该弹出一个对话框显示节点的序号
//但它总是会显示节点数目
var add_the_handlers = function(nodes){
for(var i = 0; i < nodes.length; i++){
nodes[i].onclick = function(e){
alert(i)
}
}
}
var li = document.getElementsByTagName("li")
add_the_handlers(li)
//结束糟糕例子
add_the_handlers函数的本意是想传递给每个事件处理器一个唯一值(i),但它未能达到目的,因为事件处理器函数绑定了变量 i 本身,而不是函数在构造时的变量i的值
//改良后的例子
var add_the_handlers = function(nodes){
var helper = function(i){
return function(e){
alert(i);
}
}
var i;
for(i = 0; i < nodes.length; i += 1){
nodes[i].onclick = helper(i)
}
}
var li = documentsByTagName("li");
add_the_handlers(li);
避免在循环中创建函数,它可能只会带来无畏的计算,还会引起混淆,正如上面的糟糕例子。我们可以先在循环之外创建一个辅助函数,让这个辅助函数再返回一个绑定了当前 i 值的函数,这个就不会导致混淆了
摘自《JavaScript语言精粹》一书