Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Matthew Francis
Matthew Francis
6,967 Points

Variables in for-loops

I'm confused with this code. I know that "var" is techincally a global variable, but I am still confused on how the code works. If someone could guide me step by step, it would be amazing!

for(var i = 0; i < buttons.length; i++) { 
 //for-loop will iterate once everything in the block is executed
      const button = buttons[i];  //in the first iteration, i = 0
      button.addEventListener("click", function() {
          alert("Button " + i + " Pressed"); //since this is still in the first iteration, i = 0. But apparently it is 10. Why is that?
      });
 //moves unto the next iteration, i = 1
  }

Code in better format (for others reading this):

for(var i = 0; i < buttons.length; i++) { 
 //for-loop will iterate once everything in the block is executed
      const button = buttons[i];  //in the first iteration, i = 0
      button.addEventListener("click", function() {
          alert("Button " + i + " Pressed"); //since this is still in the first iteration, i = 0. But apparently it is 10. Why is that?
      });
 //moves unto the next iteration, i = 1
  }

2 Answers

Seth Kroger
Seth Kroger
56,403 Points

Because i is in the global scope due to using var the callback you use in addEventListener will use the value of that global variable at the time the button is pressed, and not the value when the callback is created. Since the buttons will be pressed after the for loop is finished, i will be 10.

Using let instead of var will allow the current value of i to be "closed over" when the function is created, which sounds more like what you intend.

Tim Knight
Tim Knight
28,863 Points

Matthew—

I'm assuming there's more to this code than you've posted right? What are you using to build the buttons array?

var as a variable assignment is actually block scoped so for example var i in this case only exists within the scope of the block (e.g. for loop). Not keep in mind the const assignment is meant to be a constant or a variable that can be assigned to the block scope that doesn't change... it's constant. Alternatively within ES6 you can use let, like let button = .... Also another suggestion, and you'll have to forgive me that I'm not sure if this code comes from a course exercise, but it's best to avoid looping over the creation of a function. Instead create a function on the outside and pass the object in the loop into that function. I hope that gives some clarity as you're reading through that.

Seth Kroger
Seth Kroger
56,403 Points

var is function-scoped (or global if not in a function), not block-scoped. let and const were created to put block-scoping into JavaScript.

Tim Knight
Tim Knight
28,863 Points

Ah yes Seth you're correct. I misspoke using block-scope when I meant function-scoped. Thank you for catching that.