我在网上找到以下代码,在我的网站上插入一个时钟。在startTime()函数的最后一行中声明了一个变量t。然而,t中的代码似乎在没有被调用的情况下触发(这很明显,因为时钟在站点中完美运行)。
为什么这段代码有效?
我知道将函数指定为变量,这些函数在赋值时不会触发但需要调用。我也尝试了以下代码,而没有将setTimeout分配给t,它也有效。将它分配给变量有什么意义?
我是javascript的新手,所以任何可以帮助我理解这里发生的事情的解释都会很棒。
提前致谢!
代码:
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('timeLink').innerHTML = "Time: " +
h + ":" + m + ":" + s;
var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
答案 0 :(得分:2)
这一行:
var t = setTimeout(startTime, 500);
表示在500毫秒延迟后,应调用startTime
函数。由于此代码在startTime
内,因此该函数变为递归。 t
变量将接收一个代表计时器特定实例的数字。如果您希望使用clearTimeout()
功能取消计时器,可以在以后使用...您可以将它的引用传递给您要取消的计时器,如下所示:
clearTimeout(t);
看看这个小提琴,看看setTimeout()
返回的实际值:https://jsfiddle.net/34s2g1f4/6/
顺便说一下,更简化的时钟代码是:
window.addEventListener("DOMContentLoaded", function(){
var timeLink = document.getElementById('timeLink');
var t = null;
// The parenthesis around this function make it a function
// expression and the extra set of parenthesis at the end
// cause the function to invoke itself. This syntax is also
// known as an "Immediately Invoked Function Expression"
(function startTime() {
timeLink.innerHTML = "Time: " + new Date().toLocaleTimeString();
t = setTimeout(startTime, 900);
}());
});
此代码每900毫秒更新一次,而不是每500毫秒更新一次(因此它自称近一半的时间,但仍保持时间准确)。
setTimeout()
函数创建“一次性”计时器。定时器关闭后,调用提供的函数引用,这是它的结束,但在你的情况下,提供的函数引用是包含setTimeout()
的函数,所以在第一次定时器关闭后,它调用再次使用当前功能,导致设置另一个“一次性”计时器,依此类推。当函数调用自身时,它被称为“递归函数”。
获得此行为的另一种方法是使用setInterval()
,它会创建一个重复计时器,以您提供的间隔重复调用其功能。它看起来像这样:
window.addEventListener("DOMContentLoaded", function(){
var timeLink = document.getElementById('timeLink');
// Here, the call to start the timer is outside of the function
// so startTime will not be recursive, it will just be called
// repeatedly every 9/10's of a second.
var t = setInterval(startTime, 900);
});
function startTime() {
timeLink.innerHTML = "Time: " + new Date().toLocaleTimeString();
}
尽管接受的答案表明(这大多是错误的),setTimeout()
和setInterval()
已经标准化并且已经有一段时间了。来自:https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
答案 1 :(得分:0)
分配变量时,会评估右侧,并将评估结果放入变量中。
所以如果你写:
var a = 5 + 6;
然后解释器将评估5 + 6,得到11的结果,并将a分配给数字11
功能也是如此。如果你写:
function someFunction() {
return 9;
}
var x = someFunction();
解释器将评估someFunction
,调用函数,得到9的结果,并将变量赋值为9。
这也适用于您的示例。
var t = setTimeout(startTime, 500);
口译员将:
setTimeout(startTime, 500)
,然后但是,您实际上并不需要变量t
,因为它始终具有值null
并且从未使用过它。在你的功能结束时,你可以写setTimeout(startTime, 500);
,它会做同样的事情。
<强>摘要强>
函数实际上在赋值时触发,因此可以对它们进行求值以返回赋给变量的值。
希望清理它!
答案 2 :(得分:0)
调用setTimeout()并将返回值赋给var t。此实例中的返回值是此setTimeout实例唯一的ID。