【发布时间】:2016-03-07 07:12:13
【问题描述】:
我今天在一个前端 Javascript 项目中工作。我会尽量简短地描述问题和解决方案。
我必须在将用户重定向到其他页面的页面上的链接中添加点击处理程序,所以我有 2 个 Javascript 数组 arrayOfRedirectLinks 和 pageLinkElements:
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));
}
}
现在这似乎有效,但我不明白为什么有效。 我带来了以下解释,我想知道是否有人可以确认它是否正确:
当我在 Javascript 中声明一个函数时,它会获取对声明它的函数范围内的变量的引用。 (即我的事件处理程序在
addEventHandlers函数中获得对link变量的引用)因为处理程序获得了对变量
link的引用。当我为link变量重新分配一个值时,点击处理程序被触发时将使用的值也会发生变化。因此,来自事件处理程序的link变量不仅仅是与link的复制,具有与添加函数处理程序时不同的内存地址和相同的值,而是它们都共享相同的内存地址,因此具有相同的值。
1234563在由于 4),当我将
link传递给单击处理程序时,它将引用立即调用函数表达式中的link变量,该变量本身不与link函数中的addEventHandlers。因此,事件处理函数中的每个link都将与其他函数隔离,并将保留arrayOfRedirectLinks[i]的值
for 循环结束时分配给link 变量。
1234563传递给函数。 2个link变量的引用不同。
这是正确的吗?
【问题讨论】:
-
TL;DR,但这看起来像是 JavaScript closure inside loops 的很长的副本,这是非常基本的东西?
标签: javascript function scope closures dom-events