从内部函数添加事件函数和传递元素时的奇怪行为

时间:2011-09-11 13:24:34

标签: javascript javascript-events

今天,当我在onclick事件中添加一个函数时,我在javascript中遇到了一个奇怪的行为。

让我解释一下:
动态创建一些按钮并向其onclick事件添加功能时,如下所示:



    function createButton(a) {
        button = document.createElement("button");
            button.setAttribute("id","a"+a);
            button.innerHTML = "a"+a;
            button.onclick = function () {
                alert("Should be the same: a"+a+" and "+this.id);
            };
        return button;
    }

    for (var a=0;<3=;a++) {
        document.body.appendChild(createButton(a));
    }

按下第一个按钮时收到此消息:“应该是相同的:a0和a0”,如预期的那样。

但是当我想在不使用像这样的单独函数(createButton)的情况下做同样的事情时:



    var button;
    for (var a=0;a<=3;a++) {
        button = document.createElement("button");
        button.setAttribute("id","a"+a);
        button.innerHTML = "a"+a;
        button.onclick = function () {
            alert("Should be the same: a"+a+" and "+this.id);
        };
        document.body.appendChild(button);
    }
    a=999;

现在按下第一个按钮时收到此消息:“应该是相同的:a999和a0”

有谁知道为什么他们不会产生相同的警报?有没有办法让第二个例子像第一个一样工作? (我知道 button.onclick = "alert('Should be the same: a"+a+" and "+this.id+"'))可以解决问题,但那只是丑陋的)

任何帮助都会被评估,脚本可以在http://xc-results.com/static/stackoverflowq1.htm

查看

3 个答案:

答案 0 :(得分:0)

这是一个非常常见的问题。

警告中的a是对变量a的引用,其值为999。因此所有警报都具有相同的a = 999.

要避免这种情况,您需要在添加onclick时立即评估。

    var b = a;
    button.onclick = function () {
        alert("Should be the same: a"+b+" and "+this.id);
    };

这很可能会奏效。

答案 1 :(得分:0)

这在JavaScript中并不奇怪。

在脚本完成评估后,您正在调用alert()a等于999。想一想。

答案 2 :(得分:0)

在第二个例子中,button.onclick是一个闭包:一个函数+一些有界变量(在这种情况下,a)。这意味着a将在onclick() 评估时进行评估,而不是在定义时。在button.onclick运行的那一刻,a等于999,因此结果。