7

我对javascript比较陌生。我编写了一个简单的计数器程序,它从 10 开始倒数直到达到 1。

  <script type="text/javascript">
    function countDown(secs) {
        var element = document.getElementById("status");
        element.innerHTML = "Please wait for "+secs+" seconds";
        if(secs < 1) {
            clearTimeout(timer);
            element.innerHTML = '<h2>Countdown Complete!</h2>';
            element.innerHTML += '<a href="#">Click here now</a>';
        }
        secs--;
 --->       **var timer = setTimeout('countDown('secs')',1000);**
    }
    </script>
    <div id="status"></div>
    <script type="text/javascript">countDown(10);</script>

然后我尝试将参数传递'+secs+'给 countDown 函数。

var timer = setTimeout('countDown('+secs+')',1000);

以上更改有效。

我的问题是为什么我需要将参数传递为 '+secs+' 而不仅仅是 'secs' ?它有什么区别?

4

8 回答 8

12

利用

var timer = setTimeout(function(){
        countDown(secs)
    },1000);

或者

var timer = setTimeout('countDown('  + secs + ')',1000);

在您的情况下,问题是您使用带有无+符号变量的字符串连接(我的第二个示例)会导致语法错误

于 2013-06-13T06:15:36.843 回答
9

您的第一次尝试是语法错误:

var timer = setTimeout('countDown('secs')',1000);

您正在尝试将字符串传递给setTimeout(这是一个坏主意),但您没有正确创建字符串。

单词周围的单引号secs没有转义,因此您实际上传递的是字符串文字,countDown(后跟变量secs,然后是字符串文字)。因为字符串之间没有运算符,所以这是无效的语法。

但是,当您使用这些+符号时,您将 3 个字符串添加在一起以创建您想要的方法调用(运算 + 符用于连接 JavaScript 中的字符串):

'countDown(' + 'secs' + ')' ===  'countDown(secs)'

添加在一起的三个字符串会创建一个包含有效 JavaScript 的字符串,因此可以将其传递给setTimeout()函数。

尽管您可以将字符串传递给setTimeout(),但更好的方法是传递函数引用。

这通常使用这样的匿名函数来完成:

setTimeout(function () {
    countDown(secs);
}, 1000);

如果不需要传递参数,可以这样做:

function countDown() {
    alert("10... 9... 8...");
}

setTimeout(countDown, 1000);

请注意,将函数引用指定为变量时,不要使用()符号。当您在 JavaScript 中的函数后使用括号时,将调用该函数。

于 2013-06-13T06:20:05.930 回答
5

使用 setTimeout 的简单方法:

setTimeout(FunctionName,delay,arg1,arg2....);

在您的情况下,您可以简单地这样做:

setTimeout(countDown,1000,secs);

我建议这个链接:http: //javascript.info/settimeout-setinterval

于 2017-04-18T16:58:53.143 回答
2

阿迪特的想法是对的。我需要在一个循环中启动多个超时,它们最终都将变量设置为相同的值。这是一个小提琴,说明了为什么异步工作的唯一方法是 Aadit 的。

http://jsfiddle.net/85fmwew4/

for(i=0;i<10;i++){
    setTimeout(function(){bad(i)}, 1000)    // bad for async
    setTimeout(good, 1000, i)               // good for async
}
于 2015-10-15T17:27:34.723 回答
1

只需编写一个闭包来执行递减,如下所示:

if (secs < 1) {
    element.innerHTML = '<h2>Countdown Complete!</h2>';
    element.innerHTML += '<a href="#">Click here now</a>';
} else {
    // wait 1 second
    setTimeout(function() {
        countDown(secs - 1); // decrement and run ourselves again
    }, 1000);
}

我还删除了clearTimeout()有利于简单else条件的。

于 2013-06-13T06:19:08.657 回答
1

setTimeout函数允许您将其他参数传递给该函数。因此,您可以按如下方式重写代码:

var timer = setTimeout(countDown, 1000, secs);

除了一些旧版本的 IE 之外,所有主流浏览器都支持它。更多细节请看这个问题:为什么 Underscore.js 有延迟功能?

于 2013-06-13T06:20:45.463 回答
1

现在有了现代浏览器中最近的 javascript 优化,您可以简单地执行以下操作:

var timer = setTimeout( countDown( secs ) , 1000 );

于 2017-01-28T19:15:33.750 回答
0

这是唯一对我有用的东西(在 node.js 中将变量传递给 setTimeout):

setTimeout(function(teamNum,zeroBase,position) {
    spawnAI(roomIndex, 'scout', teamNum, position);
}, timeToSpawn,teamNum,zeroBase,position);
于 2016-03-22T21:02:18.737 回答