Javascript 函数无法正确接收参数

Javascript function doesn't receive an argument correctly

本文关键字:参数 函数 Javascript      更新时间:2023-09-26

可能的重复项:
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的参数始终是-1MyFunc1函数应创建四个图像,每个图像都有一个 onclick 事件。当您单击每个图像时,MyFunc2 函数应显示相应的 i 值。看起来 i 值没有为创建的每个事件和图像元素"保存",而只是它的"指针"。

谢谢!

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

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

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

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

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

这是一个正常情况,并且对闭包有误解,看到这个线程,你可能会得到一些线索,解决这个问题的简单方法是用一个 立即调用的函数表达式包装你的 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));
    }
}

您正在捕获一个在循环内发生变化的变量,因此您始终获得 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);
    }
},