Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Erik Nuber
20,629 PointsLooking for answer for a for loop alert...
for(var i = 0; i < 5; i ++){
setTimeout(function(){
alert(i);
}, 200 * i);
}
I am looking to find out what the output of this would be.
I ran it in the console and it comes out with 5 several times. I am trying to figure out why. It isn't from a lesson, it is something I saw online and, don't seem to understand why it is doing that.
4 Answers
Chris Shaw
26,676 PointsHi Erik,
Firstly, I recommend you have a read of Posting Code to the Forum when posting code.
As for your question, the reason the number 5 appears for each alert is because your for loop finishes executing long before each setTimeout declaration executes which results in the variable i storing the last value assigned to it. This can be overcome a couple of different ways, one of the older but yet still very common methods is to use a function as seen below.
for (var i = 0; i < 5; i ++) {
createTimeout(i);
}
function createTimeout(num) {
setTimeout(function() {
alert(num);
}, 200 * num);
}
What this is doing is creating a reference to i at the time createTimeout is executed which prevents the value of i from appearing as 5 for each pass of the for loop.
Another way we can get around this is by using the bind method which allows us to change the scope of the function and pass it parameters, similar to how we use the function above - just inline.
for (var i = 0; i < 5; i ++) {
setTimeout(function(num) {
alert(num);
}.bind(null, i), 200 * i);
}
It might look confusing, but this is becoming the preferred method for assigning references of variables to functions without needing to create entirely new function declarations which may not always be what you want. And for clarity, null in the above example refers to the context of this, as we have no need for this we can safely have the browser assign this to the window object which is default when null and undefined are used.
Happy coding!
Erik Nuber
20,629 PointsThank you, and I apologize for not checking my question and wrapping it properly in the ` markers. I do know better.
if possible could you still further explain the function? I still don't get what the 200 * num is doing.
When it is corrected, based on the code, it is taking i, setting it 0-4 and running the function. Passing it to the function createTimeout and alerting the num but then what is the next part for?
Chris Shaw
26,676 PointsSure!
200 * num is doing the exact same thing your original code does where you have 200 * i, the difference being is num refers to the value of i that was passed to the createTimeout function whereas in your code you just used i directly.
Broken down, this is how the execution looks.
- The
forloop begins and assignsithe value of0 - within the
forloop code block, we declare a call to ourcreateTimeoutfunction and pass it a reference to the value ofiat that given time - we then use that reference value as a parameter in our
createTimeoutfunction - finally; we declare out
setTimeoutcode in the same manor as your original example with the exception thatibecomesnum - code execution inside the
createTimeoutfunction is complete, go back to step one until the value ofiequals 4
[...] but then what is the next part for?
Which part are you referring to?
Erik Nuber
20,629 PointsOk, I do understand that the i is becoming num as an argument. What I don't understand is what num is actually doing altogether. It is being displayed in an alert but, after that we have num * 200 which seems to be extraneous code. From what i can tell it is just doing multiplication to be doing just that...multiplication.
I found the original code in examples of what employers ask job applicants. So I genuinely had no idea what it would put out. I assume that they are looking for people that answer 0 thru 4 being alerted as it's somewhat a trick if you don't fully understand javaScript. That is why I asked why is five alerted 5 times originally. I have understood your answers which I greatly appreciate.
The part that still seems extraneous as mentioned above is the num * 200. What is the purpose of that. I understand it should be corrected as you did so that 0-4 gets passed thru. but then we just get 0, 200, 400, 600, 800 that seems to do nothing. Is it just doing nothing?
Chris Shaw
26,676 PointsRight! The confusion with this comes from the fact that alerts appear to stop code execution, but because the delays are only 200 milliseconds apart from one another they become void. This might sound even more confusing, but it comes down to the fact that one whole second isn't a long time – therefore the browser simply stacks each alert one after the other making it appear as though our delay is doing nothing.
Real-world usage?
None, really! However, using the simplified code with bind, the below example would be a better example as it spans the alerts out over a 5 second period which will show a much more obvious delay.
for (var i = 0; i < 5; i ++) {
setTimeout(function(num) {
alert(num);
}.bind(null, i), 1000 * i);
}
Hope that helps.
Erik Nuber
20,629 PointsThank you for the help. Really appreciate it.