JavaScript的闭包是在面试的时候常见的一个问题,其实在实际的工作中,你可能使用到了闭包,但是没有意识到期间就是闭包。
这里,我通过一个小例子来说明闭包的使用。
Q1:下面的这段html ,每行鼠标移动上后变为灰色
<div>
<ul id="list">
<li>第一个</li>
<li>第二个</li>
<li>第三个</li>
<li>第四个</li>
</ul>
</div>
这个是不是小case嘛:
<script type="text/javascript">
// JavaScript 闭包应用
var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组
for (var i = 0; i < list_obj.length; i++) {
list_obj[i].onmousemove = function() {
this.style.backgroundColor = "#cdcdcd";
}
list_obj[i].onmouseout = function() {
this.style.backgroundColor = "#FFFFFF";
}
}
</script>
不要着急,
Q2: 点击每列,显示相应的索引值:
如果你想当然的像下面这样写:
list_obj[i].onclick = function() {
alert("这是第" + i + "记录");
}
非常遗憾的告诉你,每次输出结果都一样,输出3。
这是为什么呢?
让我们看看上面那段代码,
其实这里for循环已将整个列表循环了一遍,并执行了i++,所以这里i变成了3,
那么有什么好的办法解决这个问题吗? 那就是“闭包”了
看看什么是闭包:
闭包时是指内层的函数可以引用存在与包围他的函数内的变量,即使外层的函数的执行已经终止。
解决办法:
方法一:
list_obj[i].onclick = (function(i){
return function(){
alert(i+1);
}
})(i);
方法二:
var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组
for (var i = 0; i < list_obj.length; i++) {
list_obj[i].onmousemove = function() {
this.style.backgroundColor = "#cdcdcd";
}
list_obj[i].onmouseout = function() {
this.style.backgroundColor = "#FFFFFF";
}
/*list_obj[i].onclick = function() {
alert("这是第" + i + "记录");
}*/
var col = new bind_li(i);
list_obj[i].onclick = col.clickFunc;
}
function bind_li(i) {
this.clickFunc = function() {
alert("这是第" + (i + 1) + "记录");
}
}
方法三:
var li = document.getElementsByTagName('li');
for(var i=0,l=li.length;i<l;i++){
(function (o,i){
o.onclick = function (){
alert(i);
}
})(li[i],i)
};
这里,推荐阮一峰的 学习Javascript闭包(Closure)