使用setInterval逐个打印数字,我得到Uncaught ReferenceError

时间:2012-05-18 10:07:31

标签: javascript jquery setinterval

我想在我的代码之后逐个打印数字1到4:

脚本

<script>
$(document).ready(function(){
var b=1;
function cal(){

$('#print').html(b + '<br/>');
b++;
};
setInterval("cal()",5000);
})
</script>

HTML

<div id="print"></div>

但它不起作用,显示以下错误:

  

未捕获的ReferenceError:未定义cal

为什么会这样,我该如何解决?

3 个答案:

答案 0 :(得分:3)

修复

如何使用setInterval

这是使用setInterval()正确方式(稍后会解释):

setInterval(cal, 5000);

编写此代码的可能方法

$(document).ready(function(){
    var b = 0;
    function cal() {
        b++;
        $('#print').html(b + '<br/>');
        if (b === 4) {
            clearInterval(to);
        }
    };
    var to = setInterval(cal, 5000);
});​

jsFiddle Demo

当然还有改进的地方,例如你可以缓存$('#print')。您不需要每次都获取它。

...
var $print = $('#print'); //save it to a variable
function cal() {
    b++;
    $print.html(b + '<br/>'); //use the cached version
    ...

问题

字符串而不是函数 - &gt; eval <!/ H3>

虽然技术上可以pass a string to setInterval as its first parameter,但它等于使用eval。我们知道eval is evil,只有在你真正了解自己在做什么的情况下才使用它。这同样适用于setTimeout。无论what you have seen on w3schools和其他过时资源,都不应将字符串传递给这些方法。通过一个功能。

eval setInterval

的范围

evalsetInterval()一起使用的一个问题是它尝试在全局范围内的字符串中运行您的代码,这就是您收到错误的原因。 setIntervalwindow上定义,并在其范围内运行。您处于传递给document.ready()的闭包范围内,该函数在此范围内定义。 eval尝试在不存在的全局范围内找到它。

答案 1 :(得分:2)

你也可以试试这个:

var b = 1;
function call() {
    $('#print').append(b + '<br/>');
    b++;
    setTimeout(function() {
        if (b < 5) call();
    },5000);
};
call();

<强> DEMO

答案 2 :(得分:1)

不是提供cal()函数的字符串引用,而是给setInterval函数引用本身:

var b = 1;    
function cal() {
    $('#print').html(b + '<br/>');
    b++;
};
setInterval(cal, 1000);

Example fiddle


此外,您当前的代码将在4次迭代后继续调用间隔,因此有点浪费。您可以将此更改为具有延迟的for循环,或者在4次迭代后销毁对计时器的引用,如下所示:

var b = 1;    
function cal() {
    $('#print').html(b + '<br/>');
    b++;
    if (b > 4)
        clearInterval(timer);
};
var timer = setInterval(cal, 1000);

Example fiddle