Javascript函数没有正确接收参数

时间:2012-05-17 14:32:12

标签: javascript function arguments

  

可能重复:
  JavaScript closures and variable scope
  Assign click handlers in for loop

我有这个脚本:

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 值并非为每个创建的事件和图像元素“保存”,而只是“指针”。

谢谢!

3 个答案:

答案 0 :(得分:2)

您应该熟悉JavaScript closures的概念,以了解发生这种情况的原因。如果你是,那么你应该记住

的每个实例
function() { MyClass.MyFunc1(i); };

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

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

或使用具有正确i值的显式创建的闭包。

答案 1 :(得分:1)

这是正常情况并且误解关闭,请参阅this thread,您可能会得到一些线索,解决此问题的简单方法是将包装为具有立即调用函数表达式

的循环体
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));
    }
}

答案 2 :(得分: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);
    }
},