gpt4 book ai didi

javascript - 与 lambda 函数参数混淆

转载 作者:行者123 更新时间:2023-11-27 23:59:57 25 4
gpt4 key购买 nike

我尝试在 for 循环中将 setTimeout 与 lambda 函数一起使用,但它仅捕获 for 循环的最终迭代中 lambda 函数内容的最后一个参数。在 C# 中,我们可以创建一个新变量,每次将其传递给新的 lambda 函数时作为参数传递,但这在 javascript 中似乎不起作用。有什么线索吗?

我说的具体函数是setElementsByIdTimed()

var gElems = new Array();

document.addEventListener("DOMContentLoaded", function (event) {

//setElementsById('icon_anim_start' , "icon_anim_end");
//setTimeout(function() {setElementsById('icon_anim_end' , "icon_anim");} , 500);

var delay = setElementsByIdTimed('icon_anim_start' , "icon_anim_end" , 250);
setTimeout(function() {setElementsById('icon_anim_end' , "icon_anim");} , delay);
});

function getElementsById (elementID){
var elementCollection = new Array();
var allElements = document.getElementsByTagName("*");
for(i = 0; i < allElements.length; i++){
if(allElements[i].id == elementID)
elementCollection.push(allElements[i]);

}
return elementCollection;
}

function setElementsById (elementID, newID) {
var elems = new Array();
elems = getElementsById(elementID);

for (var i = 0; i < elems.length; i++)
{
elems[i].id = newID;
}
}


function setElementsByIdTimed (elementID, newID , ms) {
var elems = new Array();
elems = getElementsById(elementID);
console.log("elems.length: " + elems.length);
gElems = elems;


for (var i = 0; i < elems.length; i++) {
var index = i
setTimeout(function() {
setElementId(index, newID);
}, ms * i);
}

return ms * (elems.length-1);
}

function setElementId (index , newID) {
console.log ("gElems.length: " + gElems.length + " index: " + index);
gElems[index].id = newID;
}
})

最佳答案

这是一个经典的 JavaScript 闭包问题。基本上,索引变量只有一个实例,并且是在 lambda 函数上下文之外声明的。因此每个 lambda 函数都使用相同的索引,并且它们在循环完成后执行,因此每次调用时索引看起来都超出范围。

要使其正常工作,index 必须具有闭包范围:

function setElementsByIdTimed(elementID, newID , ms)
{
var elems = new Array();
elems = getElementsById(elementID);
console.log("elems.length: " + elems.length);
gElems = elems;


for(var i = 0; i < elems.length; i++)
{
var index = i
setTimeout( setClosure(index,newID), ms * i);
}

return ms * (elems.length-1);
}
function setClosure( index, newID ) {
// this lambda is called after the timeout elapses
return function() {
setElementId(index, newID);}
}

你也可以玩一个自调用技巧,但这有点令人费解:

function setElementsByIdTimed(elementID, newID , ms)
{
var elems = new Array();
elems = getElementsById(elementID);
console.log("elems.length: " + elems.length);
gElems = elems;


for(var i = 0; i < elems.length; i++)
{
var index = i
setTimeout( (function(idx,nid) {
return function () {
setElementId(idx,nid);}
})(index, newID),
ms * i);
}

return ms * (elems.length-1);
}

这些实际上是相同的解决方案,但第一个语法可能更容易掌握。

关于javascript - 与 lambda 函数参数混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31900568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com