将循环中的计数器分配给变量不会保留其当前值

时间:2016-10-19 14:19:36

标签: javascript

我不明白下面的行为。

我希望下面的脚本能够执行以下操作:

  1. 使用“按钮”类
  2. 获取所有元素
  3. 对于带按钮的每个元素,指定一个onclick事件
  4. 当用户点击某个按钮时,会在分配onclick时显示当前值i的提醒。
  5. 所以我希望点击“按钮1”会提示“我是按钮1”。

    相反,所有3个按钮都提醒“我是按钮3”。看起来i计数器的值不会被保留。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>Test</title>
        </head>
        <body>
            <p class="button">Button 0</p>
            <p class="button">Button 1</p>
            <p class="button">Button 2</p>
            <script>
                var buttons = document.getElementsByClassName('button');
                for (var i=0 ; i < buttons.length ; i++){
                    buttons[i].onclick = function(){
                        alert("I am button " + i);
                    };
                }
    
            </script>
        </body>
    </html>
    

    为什么会这样?我怎样才能达到预期的行为?

2 个答案:

答案 0 :(得分:2)

试试这个。它被称为Closures。它捕获变量i,因为在循环后未删除i,它会使用当前值i调用事件处理程序。所以你需要一个局部变量,你可以通过执行函数来获得它。所以我创建了一个函数,将一个变量i传递给他,在函数范围内,我有一个函数本地的变量param,这是每次迭代的新变量。

&#13;
&#13;
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Test</title>
    </head>
    <body>
        <p class="button">Button 0</p>
        <p class="button">Button 1</p>
        <p class="button">Button 2</p>
        <script>
            var buttons = document.getElementsByClassName('button');
            for (var i=0 ; i < buttons.length ; i++){
                buttons[i].onclick = (function(param){
                    return function(){
                    alert("I am button " + param);
                      };
                })(i);
            }

        </script>
    </body>
</html>
&#13;
&#13;
&#13;

或者您可以使用ES6 feature let

&#13;
&#13;
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>Test</title>
        </head>
        <body>
            <p class="button">Button 0</p>
            <p class="button">Button 1</p>
            <p class="button">Button 2</p>
            <script>
                var buttons = document.getElementsByClassName('button');
                for (let i = 0 ; i < buttons.length ; i++){
                    buttons[i].onclick = function(){
                        alert("I am button " + i);
                     }
                }

            </script>
        </body>
    </html>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

回调button.onclick是一个闭包,它在堆栈中有对i变量的引用,它等于循环中的最后一个值

相关问题