0

i wrote a simple function like a timer why does this code don't go right is says Uncaught ReferenceError: a is not defined why?

function timeee(sec) {
    document.getElementById("main").innerHTML = sec;
    --sec;
    if (sec == -1) {
        clearInterval(cleartext);
    }
}
function timer() {
    var a = document.getElementById("time").value;
    var cl = setInterval("timeee(a)", 1000);
    window.cleartext = cl;
}
ntalbs
  • 28,700
  • 8
  • 66
  • 83

3 Answers3

0

As you can see in this other question, when you use setInterval with a string, the function is run on a global scope. However, your a variable is only locally set, so the timeee() function cannot see it.

Try using:

function timer() {
    var a = document.getElementById("time").value;
    var cl = setInterval(function() { timeee(a) }, 1000);
    window.cleartext = cl;
}

Or if you really want to use a string, define a as a global variable:

var a;
function timer() {
    a = document.getElementById("time").value;
    var cl = setInterval("timeee(a)", 1000);
    window.cleartext = cl;
}
Community
  • 1
  • 1
dwitvliet
  • 7,242
  • 7
  • 36
  • 62
0

why?

Scope.

Consider:

function timer() {
    var a = document.getElementById("time").value;
    var cl = setInterval("timeee(a)", 1000);
    window.cleartext = cl;
}

a is locally scoped, but timeee(a) will be called from global scope. It doesn't have access to a. Try:

    var cl = setInterval(function(){timeee(a)}, 1000);

so you keep the value of a in a closure. Note that this will keep passing the same value of a every time, so you need to address that issue too (Banana's answer is one option).

RobG
  • 142,382
  • 31
  • 172
  • 209
0

After some thought, my best guess to this would be that the reference to "a" is not a proper closure.

Think of it this way: you're passing a string to setInterval. Implicitly, when you pass a string to setInterval or setTimeout, an eval() somewhere is being called.. Because at runtime, the interpreter does not know that the variable a is being used elsewhere, it will throw it away. Then, when the eval gets executed, the argument a is not there anymore.

Now take a look at the solution to your issue:

function timer() {
    var a = document.getElementById("time").value;
    var cl = setInterval(function() { timeee(a) }, 1000);
    window.cleartext = cl;
}

Because the interpreter knows that a will still be used sometime later, it will not be destroyed. This is a proper closure.

Kodlee Yin
  • 1,089
  • 5
  • 10