使用 setInterval 逐个打印数字,我得到未捕获的引用错误

Print number one by one using setInterval, I get Uncaught ReferenceError

本文关键字:错误 引用 setInterval 打印 数字 使用      更新时间:2023-09-26

我想一个接一个地打印数字 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>

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

捕获的引用错误:未定义 cal

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

修复

如何使用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 演示

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

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

问题所在

字符串而不是函数 -> eval

虽然从技术上讲,您可以将字符串作为其第一个参数传递给setInterval,但它等于使用 eval 。众所周知,eval是邪恶的,只有当你真的知道自己在做什么时,才使用它。这同样适用于 setTimeout .无论你在w3schools和其他过时的资源上看到了什么,你都不应该将字符串传递给这些方法。传递一个函数。

eval的范围与setInterval

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

你也可以试试这个:

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

演示

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

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

示例小提琴


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

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

示例小提琴