JavaScript Scoping. Callbacks and Loops

I just ran into this issue last night. The problem: I had a loop that was adding a callback to a method. Something like this:

for(var i=0;i<10;i++){
    $myElement.on('some-event', function(){
        DoSomethingWith(i);
    });
}

What I expected was that the value of the i variable at the time it was called would be used in my callback method. However, this was not the case… the i variable was the same in every single callback.

See this JSFiddle for an example.

The reason for this? JavaScript variable hoisting.  Before your code is executed it is scanned and the variables are processed. This has the effect of moving your variables to the top of the current function regardless of where in the function they are defined. (Except for in cases where you are implicitly declaring global variables).

So, in our situation we’ve defined var i. This is processed before the loop is processed and it is as if we wrote this:

var i;
for(i=0;i<10;i++){
    $myElement.on('some-event', function(){
        DoSomethingWith(i);
    });
}

Now it becomes a bit more clear why we are running into the issue with i being the same. The reason is because by the time the callback is executed the for loop has already run and the value of the i variable is already 10.

The solution, as far as I can tell, is to use an IIFE to scope the variable correctly in order store the current value for later. It looks ugly and it feels hacky… but it seems to be what is necessary. Update: It appears that you can also use .bind to set the value correctly as well.

var i;
for(i=0;i<10;i++){
    $myElement.on('some-event', 
        (function(i){
            return function(){
                DoSomethingWith(i);
            };
        })(i);
    );
}

And the JSFiddle to demonstrate.

Example With .bind

var i;
for(i=0;i<10;i++){
    $myElement.on('some-event', DoSomethingWith.bind(undefined, i));
}

Building StackOverflow Reputation – One Answer a Day

So. I’m a little low in the reputation department of StackOverflow. I mean, my reputation is ok, but it’s not AWESOME. And I need my rep to be awesome because well it’s all in the name. So, I’ve come to the conclusion that I’m going to answer one StackOverflow question every day  (weekday that is… on the weekends I’ll probably be sleeping or eating pizza or sleeping. So stop expecting so much. Stop it.) How long am I going to do this? I have no idea. I plan on making this into a habitual thing.

So here is my StackOverflow reputation as of right now:
jeremysawesome StackOverflow RepRight here I’ve inserted the flair badge which should be kept up to date with my current rep points.

profile for jeremysawesome at Stack Overflow, Q&A for professional and enthusiast programmers

So we will see how the “answer a day” thing goes.

However, I’m going to try and make my answers as helpful as possible. I don’t want to just “give” an answer, I want to also explain it. I want to explain the problem and what it was I did to fix it. I want to link to relevant articles if necessary… I want my answers to serve as teaching material for anyone else who might eventually have the same question. Answering questions in this way I believe will benefit me as well as the person asking the question.

Why would answering questions benefit me? I think that it helps me personally to be able to communicate better. If I’m able to explain a problem and how I solved it to someone else, every single day, then it’ll help me level up my communication skills. If I’m able to clearly understand a problem, and how to solve it, it will help me with my debugging skills. If I don’t know how to solve a problem, then I will most likely be doing research into how to solve the problem. This, in turn, will help me to continue learning.

So let it begin, the quest to answer a StackOverflow question everyday is underway.