我们都知道javascript中的对象类型是传引用地址的而不是传值的,我今天遇到个不明白的问题就是当我把代码在点击事件写的时候令我以外的传值了,而我写到循环里面却是传的地址代码如下
这里是普通循环触发,结果是2s后三次alert,每次都是2,这是和预期的一样last给bb传递了引用地址,就是当last改变时候bb也改变了
<html>
<script>
//普通循环demo
for(i=0;i<3;i++){
        var aa = {name:"aa"};
        aa.name = i;
        last = aa;        var bb = last;
        setTimeout(function() {
            alert(bb.name);
        }, 2000);
}
</script>
</html>
下面是事件触发 就是在2s内迅速点击鼠标3次,结果2s后三次alert依次是0,1,2。我很不解,为什么这里last传给bb的不是引用地址呢??bb为什么不改变呢?很奇怪望讨论
<html>
<script>
//事件demo
    var i = 0;
    var last = null;
    document.addEventListener("click", function(event) {
        var aa = {name:"aa"};
        aa.name = i;
        last = aa;        var bb = last;
        setTimeout(function() {
            alert(bb.name);
        }, 2000);
        i++;
    });
</script>
</html>

解决方案 »

  1.   

    下面那段是个闭包,你每次点击一下,他就新var了一个bb,然后用闭包传进setTimeout了,所以每次点的都不一样,不是同一个bb
      

  2.   

    <script language="javascript">
        for(var i=0;i<3;i++){
            (function(n){
                //return function(){
                setTimeout(function(){
                    alert(n);
                },2000);
            //}
            })(i);
        }
    </script>
      

  3.   

    JS是单线程的 setTimeout会产生"延迟"效果
    上面的代码中for完成后 setTimeout会相继在2s后依次执行 
    这时候for已经执行完了,那么你得到的都是最后一个bb