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

Javascript 从函数内部添加事件函数和传递元素时的奇怪行为,javascript,javascript-events,Javascript,Javascript Events,今天,我在向onclick事件添加函数时,在javascript中遇到了一个奇怪的行为 让我解释一下: 动态创建一些按钮并向其onclick事件添加函数时,如下所示: function createButton(a) { button = document.createElement("button"); button.setAttribute("id","a"+a); button.innerHTML = "a"+a;

今天,我在向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));
    }



    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;

当按下第一个按钮时,我得到了这个消息:应该是相同的:a0和a0,正如预期的那样。 但当我想做同样的事情而不使用单独的函数createButton时,如下所示:



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



    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‘应该是相同的:a+a+和+this.id+’会起作用,但这很难看


如果需要任何帮助,请访问脚本。这是一个非常常见的问题

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

为了避免这种情况,您需要在添加onclick时立即计算

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

这很可能会起作用。

这在JavaScript中并不奇怪


脚本完成计算且a等于999后,您正在调用警报。想想看。

在第二个示例中,button.onclick是一个闭包:一个函数+一些有界变量,在本例中,是a。这意味着将在计算onclick的时刻而不是在定义onclick的时刻对其进行计算。在运行button.onclick时,a等于999,因此是您的结果。

请注意,只有当a是数字时,此选项才有效。否则,将通过引用传递并更改。你需要一个闭包来解决这个问题。谢谢你的想法,我也尝试过了,不幸的是,它产生了同样的结果。哎呀,我的错误,当我这样做的时候,得到的结果应该是一样的:a3和a0,其中a0对应于循环末尾的var b=a==3。@Radagaisus-很好的点。但是VAR B= = C++中的调用复制构造函数吗?这将导致深度复制。不确定。好的,在第一个例子中,a是在函数定义时计算的?不完全是,我不清楚。在这两种情况下,都会在按下按钮时计算a。不同之处在于:在第一种情况下,每次for循环迭代时,它都会创建一个等于0、1、2和3的新a。这4个as将在脚本运行时生存,每个onclick方法将分别引用它们。在第二个例子中,onclick方法所指的是全局a,后来被设置为999.ah,这就解释了它!我想没有办法用函数{}创建不同的a:s-那么。。嗯,我想我必须坚持第一个例子。谢谢