前言
首先,这里要对闭包有一个理解,这里就不作详细介绍了。
看以下代码:
<button>0</button> <button>1</button> <button>2</button> <button>3</button>
var button = document.getElementsByTagName("button"); var addEventListener = function(nodes){ var i; for(i = 0; i < nodes.length; i++){ nodes[i].onclick = function(e){ alert(i); } } } addEventListener(button);
这里的运行结果是怎样呢?结果是:每点击一个button,最后alert的都是2。
因为,在for循环的时候,只是在给button绑定的事件,当你点击button的时候,对应的事件才会执行,才会alert当前i的值。而在js中,函数是运行在定义它的作用域当中,只要一个函数定义在另一个函数当中,这个函数就能访问它所在函数中定义的所有变量。这里的函数则是定义addeventlistener里面,当执行onclick事件的时候,for循环已经完成,函数当中的i已经变成2,因此无论点击哪个button,alert的都是2。
利用闭包保存状态
看以下代码:
var button = document.getElementsByTagName("button"); // 改良后 var addEventListener = function(nodes){ var helper = function(i){ return function(e){ alert(i); }; }; var i; for(i = 0; i < nodes.length; i++){ nodes[i].onclick = helper(i); } } addEventListener(button);
上面的for循环当中,每循环一次,都将实时的i传给helper,当点击button时,由于alert(i)这个函数是定义在helper里面,因此它的i也是来自于helper,因此可以保存每一次遍历i的状态。从上面看出,
只要函数定义在helper当中,它就可以访问到定义在helper里面的所有变量,即使helper已经被执行完。
而且闭包是直接return一个函数,因此return的这个函数相当于在全局调用,它里面的变量会一直保存在内存当中。
参考文献:http://www.yuanlairc.com/program/closure.html