首页 > 代码库 > 闭包允许内层函数引用父函数中的变量,但是该变量是最终值
闭包允许内层函数引用父函数中的变量,但是该变量是最终值
今天在学习JavaScript的时候碰到的一个类似于如下代码的问题:
/** * <body> * <ul> * <li>one</li> * <li>two</li> * <li>three</li> * <li>one</li> * </ul> */var lists = document.getElementsByTagName(‘li‘);for(var i = 0 , len = lists.length ; i < len ; i++){ lists[ i ].onmouseover = function(){ alert(i); };}
在函数执行时,会发现弹窗显示的值总是4(即:父函数中的循环变量i的最终值),而不是我们期望的0,1,2,3.原因是:当mouseover事件调用监听函数时,首先在匿名函数( function(){ alert(i); })内部查找是否定义了 i,结果是没有定义;因此它会向上查找,查找结果是已经定义了,并且i的值是4(循环后的i值);所以,最终每次弹出的都是4。
可能的解决办法如下[1]:
//method 1
var lists = document.getElementsByTagName(‘li‘);for(var i = 0 , len = lists.length ; i < len ; i++){ (function(index){ lists[ index ].onmouseover = function(){ alert(index); }; })(i);}
//method 2var lists = document.getElementsByTagName(‘li‘);for(var i = 0, len = lists.length; i < len; i++){ lists[ i ].$$index = i; //通过在Dom元素上绑定$$index属性记录下标 lists[ i ].onmouseover = function(){ alert(this.$$index); };}
//method 3function eventListener(list, index){ list.onmouseover = function(){ alert(index); };}var lists = document.getElementsByTagName(‘li‘);for(var i = 0 , len = lists.length ; i < len ; i++){ eventListener(lists[ i ] , i);}
以上方法中,method 1 亲自测试可用,且推荐使用该方法。
Reference
[1] JavaScript中的匿名函数及函数的闭包 http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html
闭包允许内层函数引用父函数中的变量,但是该变量是最终值
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。