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

Posted

技术标签:

【中文标题】Javascript 仅设置数组中最后一项的属性【英文标题】:Javascript only sets attribute for last item in array 【发布时间】:2011-10-23 16:39:25 【问题描述】:

我有一个约 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;        
        

    ;

所以你可以看到条件是否满足,它仍然会改变属性,但我收到的错误是它只改变了数组中的最后一项。有什么想法吗?

【问题讨论】:

你到底为什么要做 setAttribute 和 .xxx?他们都做同样的事情! 哈哈哎呀,我什至没有注意到我这样做了。条件只是检查 URL 是否来自正确的域。 【参考方案1】:

这是 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;        
        

    ;

【讨论】:

【参考方案2】:

问题是变量 coName 将始终是执行任何函数时的最后一个数组值。你可以这样做:

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

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

【讨论】:

以上是关于Javascript 仅设置数组中最后一项的属性的主要内容,如果未能解决你的问题,请参考以下文章

s-s-rS:如何计算仅包含组中最后一项的总和

此结构数组中最后一项的意义

从 JavaScript 中的关联数组中获取第一项的最有效方法是啥?

JavaScript常见的数组方法

获取数组VueJS的最后一项

JavaScript——驰骋网页的脚本执行者