1

可能重复:
JavaScript 闭包和变量范围
在 for 循环中分配点击处理程序

我有这个脚本:

var MyClass = {
    MyArray: new Array(0, 1, 2, 3, 4),

    MyFunc1: function() {
        var i = 0;
        for (i = MyClass.MyArray.length - 1; i>=0; i--) {
            var cen = document.getElementById("cen_" + i); // It is an img element
                cen.src = "col.png";
                cen.className = "cen_act";
                cen.onclick = function() { MyClass.MyFunc1(i); };
            } else {
                cen.src = "no.png";
                cen.className = "cen";
                cen.onclick = null;
            }
        }
    },

    MyFunc2: function(id) {
        alert(id);
    }
}

我的问题是,在这一行:cen.onclick = function() { MyClass.MyFunc1(i); };发送到的参数MyFunc2始终是-1。该MyFunc1函数应该创建四个图像,每个图像都有一个onclick事件。当您单击每个图像时,MyFunc2 函数应显示相应的 i值。看起来i值不是为每个创建的事件和图像元素“保存”的,而只是它的“指针”。

谢谢!

4

3 回答 3

2

您应该熟悉JavaScript 闭包的概念才能理解为什么会发生这种情况。如果你是,那么你应该记住

function() { MyClass.MyFunc1(i); };

函数闭包包含i的值-1(因为它是整个循环完成执行后此变量的最终值。)为避免这种情况,您可以使用bind

cen.onclick = (function(i) { MyClass.MyFunc1(i); }).bind(null, i);

或使用具有适当i值的显式创建的闭包。

于 2012-05-17T14:37:09.137 回答
1

这是一个正常的情况和对闭包的误解,看到这个线程,你可能会得到一些线索,解决这个问题的简单方法是用立即调用函数表达式包装你的for循环体

MyFunc1: function() {
    var i = 0;
    for (i = MyClass.MyArray.length - 1; i>=0; i--) {
        (function(i) {
            var cen = document.getElementById("cen_" + i); // An img element
                cen.src = "col.png";
                cen.className = "cen_act";
                cen.onclick = function() { MyClass.MyFunc2(i); };
            } else {
                cen.src = "no.png";
                cen.className = "cen";
                cen.onclick = null;
            }
        }(i));
    }
}
于 2012-05-17T14:36:49.357 回答
1

您正在捕获一个在循环内发生变化的变量,因此您总是得到 i 的最后一个值。

您可以通过创建闭包轻松解决此问题:

MyFunc1: function() {
    var i = 0;
    for (i = MyClass.MyArray.length - 1; i>=0; i--) {
        (function(i) {

        var cen = document.getElementById("cen_" + i); // An img element
            cen.src = "col.png";
            cen.className = "cen_act";
            cen.onclick = function() { MyClass.MyFunc2(i); };
        } else {
            cen.src = "no.png";
            cen.className = "cen";
            cen.onclick = null;
        }
       })(i);
    }
},
于 2012-05-17T14:37:48.247 回答