简体   繁体   中英

Number doesn't update in setTimeout loop

This simple code should be counting from 0 to infinity and should be showing the next number every 100 milliseconds. The thing is when I open this in chrome the number is stuck at 0. Can somebody explain why this is happening and what I have done wrong?

 function count(a) { var no=a; no++; document.getElementById("num").innerHTML=no; setTimeout("count(no)",100); }
 <html> <head> <meta charset="utf-8"/> </head> <body onload="count(-1);"> <div id="num"></div> </body> </html>

If you pass a string to setTimeout , that will be executed as a code literal in the global scope. In the global scope, the variable no does not exist, because it's a variable scoped to the function count .

You'll want to pass the callback this way:

setTimeout(count, 100, no);

This passes the function object count , and the current value of no as an argument which will be passed to count when it's invoked.

The problem is that you're passing a string to setTimeout . As the MDN documentation for setTimeout states:

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

That is, 100 milliseconds after count has returned, "count(no)" is evaluated in the global context. count is a global function, but no was just a local variable. There is no global symbol no .

To fix this, don't use strings. Pass a function to setTimeout instead:

setTimeout(function () { count(no); }, 100);

The function () { count(no); } function () { count(no); } part is what's known as a closure , a function that uses local variables from a surrounding scope. This way you can refer to a local variable like no even after its containing function has returned.

In theory you could also do

setTimeout(count, 100, no);

but MDN warns:

Note that passing additional parameters to the function in the first syntax does not work in Internet Explorer.

Don't wrap the function reference in quotes, instead pass an anonymous function that calls count (and holds a reference to no as a closure ):

 function count(a) { var no = a; no++; num.textContent = no; setTimeout(function() { count(no); }, 100); } 
 <body onload="count(-1)"> <div id="num"></div> </body> 

You don't use the setTimeout method. It calls the input function only once after the delay. For multiple calling, you use the setInterval function. Replace Timeout with Interval. Also, since you only want to increment from a given number -1, a simple way could be to put it in a global variable and increment it over and over with the setInterval method.

Code can be something like this.

<script>
let a = -1;
function count() {
document.getElementById("num").innerHTML = (++a);
}
setInterval(count,100);
</script>

try this

<script type="text/javascript">
    var no = 0;
    function count()
    {
            no++;
            document.getElementById("num").innerHTML=no;

    }
    setInterval(count, 100);
</script>

<body>

    <div id="num"></div>

</body>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM