gpt4 book ai didi

javascript - 应用事件监听器时变量超出范围

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

为什么 i 在这段代码的 callback function 范围之外?

// All menu items collection
var menuItems = document.getElementsByClassName('menu-item');

// Loop trough all menu items and attach
// event listeners.
for (var i = 0; i < menuItems.length; i++) {
// Check if element truely exsists
if (menuItems[i]) {
menuItems[i].addEventListener('click', function(e){
////////////////////////////////
// NOTE: i, is out of scope! //
//////////////////////////////
var icon = menuItems[i].children[1],
submenu = menuItems[i].children[2];

// Change icon color
if (icon.style.background !== "blue") {
icon.style.background = "blue";
} else {
icon.style.background = "red";
}

// Show/hide submenu
if (submenu.style.display !== "block") {
submenu.style.display = "block";
} else {
submenu.style.display = "none";
}
});
}
}

最佳答案

变量 i 没有超出范围。只是事件处理程序将在循环完成后的某个时间被调用,因此变量 i 的值指向 menuItems 数组之外。

将代码包装在一个函数中,以创建一个作用域,您可以在其中为每次迭代复制变量:

for (var i = 0; i < menuItems.length; i++) {
// Check if element truely exsists
if (menuItems[i]) {

(function(i){

menuItems[i].addEventListener('click', function(e){
var icon = menuItems[i].children[1],
submenu = menuItems[i].children[2];

// Change icon color
if (icon.style.background !== "blue") {
icon.style.background = "blue";
} else {
icon.style.background = "red";
}

// Show/hide submenu
if (submenu.style.display !== "block") {
submenu.style.display = "block";
} else {
submenu.style.display = "none";
}
});

})(i);

}
}

由于事件处理程序使用 i 变量,它将被捕获到该函数的闭包对象中。每个事件处理程序都有一个单独的闭包对象,但如果没有函数包装器为每次迭代创建一个单独的 i 变量,所有闭包都会捕获相同的变量。

函数的闭包包含函数从外部作用域使用的所有局部变量。除非 menuItems 是一个全局变量,否则它也会在闭包中。

关于javascript - 应用事件监听器时变量超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19203992/

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