上一篇
中,我们使用的闭包是这样的。
1 2 3 4 5 6 7 8 9
|
var elems = document.getElementsByTagName('div'); for(var i=0, len=elems.length; i<len; i++){ (function(i){ var div = elems[i]; div.onclick = function(){ alert(div.innerHTML); }; })(i); }
|
但是有没有觉得这个闭包“包”的范围太大了,可以精简一下。
1 2 3 4 5 6 7 8 9
|
var elems = document.getElementsByTagName('div'); for(var i=0, len=elems.length; i<len; i++){ var div = elems[i]; div.onclick = (function(div){ return function(){ alert(div.innerHTML); }; })(div); }
|
这里
onclick
绑的函数是一个匿名的自执行函数,该匿名函数以当前的div作为参数,自执行后又返回了一个函数才是真正的
onclick
函数。虽然比起前面一段代码,这段代码的闭包范围是小了点,但只是把前面闭包内部声明的变量div,变成了这段代码里匿名函数的参数。本质上闭包对变量的存储开销并没怎么省,上面的代码还能再改进。
1 2 3 4 5 6 7 8
|
var elems = document.getElementsByTagName('div'); for(var i=0, len=elems.length; i<len; i++){ elems[i].onclick = (function(i){ return function(){ alert(elems[i].innerHTML); }; })(i); }
|
这样的话,闭包中“记住”的变量更小。但是有没有注意到,在循环中会多次去生成同一个匿名函数(只不过自执行时传入的参数值不同),因此可以使用函数的引用进一步优化上面的代码。
1 2 3 4 5 6 7 8 9 10
|
var elems = document.getElementsByTagName('div'); var callback = function(i){ return function(){ alert(elems[i].innerHTML); }; };
for(var i=0, len=elems.length; i<len; i++){ elems[i].onclick = (callback)(i); }
|
如此,
callback
函数仅存有一份,在for循环中为它传入不同的参数值进行执行,它返回的函数才是真正绑到
onclick
上的函数。