gpt4 book ai didi

Javascript 闭包作用域

转载 作者:行者123 更新时间:2023-11-29 19:18:45 24 4
gpt4 key购买 nike

我今天在一个前端 Javascript 项目中工作。我会尽量保持对问题和解决方案的描述尽可能简短。我必须将点击处理程序添加到页面上的链接,将用户重定向到其他页面,所以我有 2 个 Javascript 数组 arrayOfRedirectLinkspageLinkElements :

var arrayOfRedirectLinks, pageLinkElements;

最初我写了addEventHandlers像这样的功能:

var addEventHandlers = function() {
var i, link;
for( var i in arrayOfRedirectLinks) {
link = arrayOfRedirectLinks[i];
pageLinkElements[i].addEventListener('click', function(e) {
e.preventDefault();
window.location = link;
});
}
}

我认为这个解决方案会完成这项工作,直到......好吧,直到我打开浏览器,单击几个链接并注意到它们都将我重定向到同一个链接(arrayOfRedirectLinks 中的最后一个链接)。

最后发现我的问题和这里贴的差不多 Javascript multiple dynamic addEventListener created in for loop - passing parameters not working

事实上,那里发布的第一个和第二个解决方案都对我有用

var addEventHandlers = function() {
var i, link;
for( var i in arrayOfRedirectLinks) {
(function(link){
link = arrayOfRedirectLinks[i];
pageLinkElements[i].addEventListener('click', function(e) {
e.preventDefault();
window.location = link;
});
}(link));
}
}

var passLink = function(link) {
return function(e) {
e.preventDefault();
window.location = link;
};
};
var addEventHandlers = function() {
var i, link;
for( var i in arrayOfRedirectLinks) {
link = arrayOfRedirectLinks[i];
pageLinkElements[i].addEventListener('click',passLink(link));
}
}

现在这似乎行得通,但我不明白为什么会行得通。我带来了以下解释,我希望有人可以确认它是否正确:

  1. 当我在 Javascript 中声明一个函数时,它会获取对声明它的函数范围内的变量的引用。 (即我的事件处理程序在 link 函数中获取对 addEventHandlers 变量的引用)

  2. 因为处理程序获得了对变量 link 的引用.当我为 link 重新赋值时变量,当点击处理程序被触发时将使用的值也会改变。所以 link来自事件处理程序的变量不是简单地复制 link具有与添加函数处理程序时不同的内存地址和相同的值,但它们共享相同的内存地址,因此具有相同的值。

  3. 由于 2) 中所述的原因,所有点击处理程序都将使用重定向到相同的 link。 , 最后一个link在数组中 arrayOfRedirectLinks因为这是将分配给 link 的最后一个值for 末尾的变量循环。

  4. 但是当我通过 link变量作为另一个函数的参数,它创建的新作用域和 link在该范围内实际上仅共享它的初始值与 link 的值传递给函数的参数。 2 link 的引用文献变量不同。

  5. 因为 4),当我通过 link到点击处理程序,它将引用 link立即调用的函数表达式中的变量本身不与 link 共享同一地址在addEventHandlers功能。因此每个link来自事件处理函数的函数将与其他函数隔离,并将保留 arrayOfRedirectLinks[i] 的值

这是正确的吗?

最佳答案

这是关键点:

var i, link;
for( var i in arrayOfRedirectLinks) {
link = arrayOfRedirectLinks[i];
pageLinkElements[i].addEventListener('click', function(e) {
e.preventDefault();
window.location = link;
});
}

这里只有一个 link 变量。请注意,只有在单击链接时才会调用 addEventListener 回调函数。

到那时,变量 link 有了它的最终值,所有事件处理函数都共享它。

所以所有的链接都做同样的事情。

最简单的解决方案(除了更广泛的重构):

for(var i in arrayOfRedirectLinks) {      
(function(i) {
var link = arrayOfRedirectLinks[i];
pageLinkElements[i].addEventListener('click', function(e) {
e.preventDefault();
window.location = link;
});
}(i));
}

关于Javascript 闭包作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34053005/

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