cari

Rumah  >  Soal Jawab  >  teks badan

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<code><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>

</code>

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<code><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>

</code>

执行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]的工作过程一样。

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

天蓬老师天蓬老师2896 hari yang lalu413

membalas semua(8)saya akan balas

  • 怪我咯

    怪我咯2017-04-10 15:23:12

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

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

    balas
    0
  • PHP中文网

    PHP中文网2017-04-10 15:23:12

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    <code>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);

        }

    };

    </code>

    而不是这样写

    1

    2

    3

    4

    5

    6

    7

    8

    9

    <code>window.onload=function(){

        var aBtn = document.getElementsByTagName('input');

        for(var i=0;i<aBtn.length;i++){

            aBtn[index].onclick=function(){

                    alert(index);

                };

        }

    };

    </code>

    balas
    0
  • 黄舟

    黄舟2017-04-10 15:23:12

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

    balas
    0
  • 高洛峰

    高洛峰2017-04-10 15:23:12

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

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

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

    balas
    0
  • ringa_lee

    ringa_lee2017-04-10 15:23:12

    1

    2

    3

    4

    5

    6

    7

    <code>        (function(index){

                aBtn[index].onclick=function(){

                    alert(index);

                };

            })(i);

     

    </code>

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

    balas
    0
  • 天蓬老师

    天蓬老师2017-04-10 15:23:12

    这就相当于这段代码

    1

    2

    3

    4

    5

    6

    7

    <code>for(var i=0; i<aBtn.length; i++){

        aBtn[i].index = i;

        aBtn[i].onclick = function(){

               alert(this.index);

        }

    }

    </code>

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

    balas
    0
  • 黄舟

    黄舟2017-04-10 15:23:12

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    <code>window.onload=function(){

        var aBtn = document.getElementsByTagName('input');

        for(var i=0;i<aBtn.length;i++){

            aBtn[index].onclick=function(){

                    alert(index);

                };

        }

    };

    </code>

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

    balas
    0
  • 黄舟

    黄舟2017-04-10 15:23:12

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

    balas
    0
  • Batalbalas