-2

Given the following javascript code:

function countdown (num) {
    for (var i = 0; i <= num; i += 1) {
        setTimeout(function () {
            alert(num - i);
        }, i * 1000);
    }
}

countdown(5);

The desired result is a countdown from 5 to 0 using alert messages. Explain why the code only alerts -1, then fix the code so it works as expected.

I found the above javascript quiz and i really don't know how to solve it. I know it's anonymous functions and it has something to do with the variables scope but i consider it a great opportunity to learn if someone could explain me why it's not working and what needs to be done in order to work. I seek the theory behind the problem and the solution.

I know i can just read about Anonymous functions but an explanation using a "real problem" will help me visualize the problem and understand it better.

Ricky Stam
  • 2,116
  • 21
  • 25
  • See http://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1, http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem and http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – bfavaretto Dec 02 '13 at 12:43
  • http://blog.abhiomkar.in/2010/07/03/javascript-code-challenge-by-dropbox-team/ – aljordan82 Dec 02 '13 at 12:44
  • People are down voting the question but i already received 3 different ways to solve the problem. Thanks for your help people. I'll study all solutions you provided. – Ricky Stam Dec 02 '13 at 12:55

3 Answers3

2

Because of the scope of i when the anonymous function is called the loop is over and iis in it's final value(-1). To solve this you can isolate a local scope with another anonymous function where you can redefine private variable i like this:

function countdown (num) {
    for (var i = 0; i <= num; i += 1) {
        (function(i) {
            setTimeout(function () {
                alert(num - i);
            }, i * 1000);
        })(i);
    }
}

countdown(5);
core1024
  • 1,882
  • 15
  • 22
0

http://jsfiddle.net/3p8FM/ You can resolve this way, binding the variables num and i

The alerts with -1 happened because the the scope of i. When the first function is really executed after the determined time, i has already the value of 6

André Junges
  • 5,297
  • 3
  • 34
  • 48
0

Change ur code as like this.. function countdown (num) {enter code here var j=0;setTimeout(function () { for (var i = 0; i <= num; i++) { j=i; alert(num-i);} }, j*1000);
}

countdown(5);

bravo
  • 11
  • 1