首页 > 看了好几个小时还是想不明白的JS代码(好像是与闭包有关),求解惑!

看了好几个小时还是想不明白的JS代码(好像是与闭包有关),求解惑!

<body>
<input type="button" value="aaa" />
<input type="button" value="bbb" />
<input type="button" value="ccc" />
<script>
window.onload=function(){
    var aBtn = document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
        (function(index){
            aBtn[index].onclick=function(){
                alert(index);
            };
        })(i);
    }
};
</script>
</body>

依次点击三个按钮aaa、bbb、ccc我觉得是3、3、3。但点击三个按钮弹出的是0、1、2,这是为什么呢?我想了好几个小时还是搞不懂......

感谢大伙给我的启发,我到犀牛书(6版)和JS高程(3版)找到了相关的知识,总结一下,劳驾帮我看看我的理解是否正确,感谢!!

<body>
<input type="button" value="aaa" />
<input type="button" value="bbb" />
<input type="button" value="ccc" />
<script>
window.onload=function(){
    var aBtn = document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
        show(i);             //在for循环中调用这个函数
    }
    function show(index){    //把函数单提出来,不用立即执行的函数
        aBtn[index].onclick=function(){
            alert(index);
        };
    }
};
</script>
</body>

执行for循环时:
当i=0时,show(0)执行, 此时index=0,==>新建一个活动对象,假设叫show0,里面保存了index=0。
内部函数表达式:aBtn[0].onclick=function(){alert(index);};

当i=1时,show(1)执行,此时index=1,==>新建一个活动对象,假设叫show1,里面保存了index=1。
内部函数表达式:aBtn[1].onclick=function(){alert(index);};

当i=2时,show(2)执行,此时index=2,==>新建一个活动对象,假设叫show2,里面保存了index=2。
内部函数表达式:aBtn[2].onclick=function(){alert(index);};

点击按钮时:
aBtn[0].onclick=function(){alert(index);};
在function(){alert(index);}中,没有找到index,去作用域链下一个活动对象中找,找到show0,这个活动对象中保存着index=0,所以aBtn[0]点击时弹出0。
aBtn[1]和aBtn[2],弹出2、3也和aBtn[0]的工作过程一样。

以上是我目前的认识,不知道对不对,劳驾您帮我看看,谢谢。


        (function(index){
            aBtn[index].onclick=function(){
                alert(index);
            };
        })(i);

这段在定义匿名函数的同时立刻调用了,而这个调用是在循环体内的,所以3次调用的i是0、1、2,所以绑定的3个onclick也是0、1、2


手机不方便打字,提供一下方向:

  1. 闭包
  2. JavaScript的函数调用是传值调用
  3. 函数作用域

闭包所接受的变量,是父函数变量的结果,不是过程


你能够自己想到是3,3,3的结果说明你已经了解到 "作用域链" 的原理了。

代码用引入Index的作用是保存当前i的值;

个人心得:
理解 "作用域链" , "闭包",可用转化成 "内存" 分配,访问去深入体会;


问下自己代码为什么这样写

window.onload=function(){
    var aBtn = document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
        (function(index){
            aBtn[index].onclick=function(){
                alert(index);
            };
        })(i);
    }
};

而不是这样写

window.onload=function(){
    var aBtn = document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
        aBtn[index].onclick=function(){
                alert(index);
            };
    }
};

这其实是一个闭包的问题,其中一个特性是“一个闭包就是当一个函数返回时,一个没有释放资源的栈区。”,完全可以用这句话解释你的问题。网上关于闭包的解释很多,如果改成这个样子就是你想要的3,3,3

window.onload=function(){
    var aBtn = document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
        aBtn[index].onclick=function(){
                alert(index);
            };
    }
};

其实楼上已经写了,我刚刚写,楼上就出来了,汗~~~~


这就相当于这段代码

for(var i=0; i<aBtn.length; i++){
    aBtn[i].index = i;
    aBtn[i].onclick = function(){
           alert(this.index);
    }
}

每次循环都把当前的i值保存了下来


看看这个本站的闭包介绍
http://.com/a/1190000002805295

【热门文章】
【热门文章】