码迷,mamicode.com
首页 > 其他好文 > 详细

闭包允许内层函数引用父函数中的变量,但是该变量是最终值

时间:2014-09-11 22:12:02      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:blog   http   io   os   使用   java   ar   strong   for   

今天在学习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 2

var 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 3

function 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

 

  

  

 

闭包允许内层函数引用父函数中的变量,但是该变量是最终值

标签:blog   http   io   os   使用   java   ar   strong   for   

原文地址:http://www.cnblogs.com/jiayouwyhit/p/3967246.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!