Javascript 只为数组中的最后一项设置属性

标签 javascript arrays attributes checkbox

我有一个大约 50 项的数组,在 javascript 中它通过这个数组来检查条件,如果满足条件,它会为要检查的复选框设置属性。它通过得很好,但每次只更改数组中的最后一项。这是代码的一部分。

for (i = 0; i < urlArray.length; i++) {
    var newImg = new Image();
    var coName = companyArray[i];
    newImg.onload = function(){
        if (condition is met){
            nStar++;

                    document.getElementById(coName).setAttribute("checked", "checked");
                    document.getElementById(coName).checked = true;
        } else {
            nStar++;

                    document.getElementById(coName).setAttribute("checked", "checked");
                    document.getElementById(coName).checked = true;
                    document.getElementById(coName).setAttribute("disabled", "disabled");
                    document.getElementById(coName).disabled = true;        
        }

    };

如您所见,无论是否满足条件,它仍会更改属性,但我收到的错误是它仅更改数组中的最后一项。有什么想法吗?

最佳答案

这是 Javascript 中异步回调的经典问题。 onload 处理程序将在一段时间后调用,在 for 循环完成很久之后,因此 for 循环中的索引被固定在它结束的末尾,局部变量 newImg 和 coName 将只有它们在循环中的最后一个值.

您希望在 onload 处理程序中使用的任何变量都必须传递到实际的函数闭包中,以便它们对每个不同的 onload 处理程序都是唯一可用的。有几种方法可以做到这一点。

这种方式使用函数闭包来捕获传入的值并使其可用于 onload 函数处理程序:

for (i = 0; i < urlArray.length; i++) {
    var newImg = new Image();
    var coName = companyArray[i];
    newImg.onload = (function (coName) {
        return function(){
            if (condition is met){
                nStar++;
                document.getElementById(coName).setAttribute("checked", "checked");
                document.getElementById(coName).checked = true;
            } else {
                nStar++;
                document.getElementById(coName).setAttribute("checked", "checked");
                document.getElementById(coName).checked = true;
                document.getElementById(coName).setAttribute("disabled", "disabled");
                document.getElementById(coName).disabled = true;        
            }
        };
    }) (coName);
}

在 Javascript 中,此方法的作用是将执行匿名函数调用的返回值分配给 onload 属性。该匿名函数调用将 coName 参数传递给它。该函数返回另一个匿名函数,该函数被指定为 onload 处理程序。但是,由于函数闭包在 javascript 中的工作方式,coName 的值在函数闭包中被捕获,并在函数闭包期间保持可供 onload 处理程序访问。人们可以把它想象成一个函数的实例,它周围有状态(局部变量的值),每次设置时都会唯一地捕获它。在这种情况下,它捕获 coName 变量的值并将其放入闭包中,在闭包中它变得唯一并且不会受到以后对 for 循环中外部 coName 变量的更改的影响。

另一种方法是将参数放在实际对象上,以便您可以从那里检索它:

for (i = 0; i < urlArray.length; i++) {
    var newImg = new Image();
    newImg.setAttribute("coName". companyArray[i]);
    newImg.onload = function() {
        var coName = this.getAttribute("coName");
        if (condition is met){
            nStar++;
            document.getElementById(coName).setAttribute("checked", "checked");
            document.getElementById(coName).checked = true;
        } else {
            nStar++;
            document.getElementById(coName).setAttribute("checked", "checked");
            document.getElementById(coName).checked = true;
            document.getElementById(coName).setAttribute("disabled", "disabled");
            document.getElementById(coName).disabled = true;        
        }

    };
}

关于Javascript 只为数组中的最后一项设置属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7004619/

相关文章:

javascript - 当没有这样的条件调用时,useEffect Hook 条件调用的 React 错误

javascript - 无法在函数中设置未定义的属性

javascript - 使用 .attr 更改 onMouseOver

java - 检测 JSP 中的下拉列表变化?

iphone - iOS 中的 NSFileSystemFileNumber 总是唯一的吗?

javascript - 解析云代码 - 获取 PFFile 的 URL

javascript - 如何将 scss 文件与 create-react-app 一起使用?

java - 如何在MapView上添加多个标记——一百多个

c++ - 基于范围的for循环的奇怪问题

javascript - 按最大匹配对字符串匹配结果进行排序