Skip to content

Instantly share code, notes, and snippets.

@jmiramant
Last active July 10, 2016 17:56
Show Gist options
  • Save jmiramant/31814c455ff60b7f5cc002338b921458 to your computer and use it in GitHub Desktop.
Save jmiramant/31814c455ff60b7f5cc002338b921458 to your computer and use it in GitHub Desktop.

Hi Student,

You've stumbled upon one of the many qwerks of JavaScript. This trips all of us JavaScript developers up. Let's look closer at the bug.

#####What's happening If you put a console.log() to reveal the value of the btnNum variable when you click each button, you'll discover it's 3 despite what button you choose. So why is this?

You're right on track with your thinking here. I see you were expecting for the loop counter btnNum to correspond to each respective value (index) in your prizes array.

There are two things that causing this bug:

  1. JavaScript scope
  2. How a for loop works

#####JavaScript scope Scope is a set of rules in JavaScript that explains where variable and functions are able to be accesses. For example:

var someFunction = function () {
  var localVariable = 'local'
}
someFunction();
console.log(localVariable) //This will be undefined since the scope of this variable is only accessible inside the 'someFunction' function

In your example, the btnNum 'counter' variable from the for loop is being passed into alert(prizes[btnNum]) when a user clicks a button. However, the scope of this btnNum variable is not limited to this Alert function. It is set in the parent scope, and there for changes each time the loop increments the counter variable.

But why is it 3? Let's look at the for loop a bit more.

#####How a for loop works If you run your loop and log the btnNum index, it appears to work just as you'd like it to.

for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
  console.log(btnNum);
}

Your output is:

0
1
2

So where does that 3 come from? Let's look a little closer at this:

The 1st time this loop runs, it:

  1. var btnNum = 0: sets btnNum to 0
  2. btnNum < prizes.length: checks if the btnNum value of 0 is less than the length of your prizes array, which is 3.
  3. btnNum++: btnNum++ is equivalent to btnNum = btnNum + 1 so it will add 1 to the btnNum 'counter' variable increasing your counter to from 0 to 1.
  4. The code inside of {} runs printing, 0

The 2nd time this loops runs, it:

  1. btnNum is equal to 1 from the increment on the last loop.
  2. btnNum < prizes.length: btnNum is less than 3, your array length, so this will run again.
  3. btnNum++: btnNum becomes 2
  4. The code inside of {} runs printing, 1

...depending on the size of the array, this will keep running until btnNum is 'not less than' the length of your array. Here's what happens in your code:

The 4th time this loop runs, it:

  1. btnNum is equal to 3 from the increment on the last loop.
  2. btnNum < prizes.length: btnNum is not less than 3, so your code won't execute and this loop is complete

Notice the value of btnNum is 3, the value you're getting when you click each button.

###How to make this work...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment