Variable out of scope when applying event listener

前端 未结 1 1948
醉酒成梦
醉酒成梦 2021-01-22 00:57

Why is i out of scope in the callback function in this code?

// All menu items collection
var menuItems = document.getElementsByClassN         


        
相关标签:
1条回答
  • 2021-01-22 01:28

    The variable i is not out of scope. It's just that the event handler will be called some time after the loop has completed, so the variable i has a value that points outside the menuItems array.

    Wrap the code in a function, to create a scope where you have a copy of the variable for each iteration:

    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);
    
      }
    }
    

    As the event handler uses the i variable, it will be captured in a closure object for that function. Each event handler will have a separate closure object, but without the function wrapper to create a separate i variable for each iteration, all the closures would capture the same variable.

    The closure for a function contains all local variables that the function uses from the outer scope. Unless menuItems is a global variable, it will also be in the closure.

    0 讨论(0)
提交回复
热议问题