JavaScript?setTimeout和setInterval的用法與區(qū)別詳解
I. 總述
首先,setTimeout()和setInterval()函數(shù)是JavaScript中兩個(gè)很重要的關(guān)于"時(shí)間的函數(shù)",因此,我們?cè)趯W(xué)習(xí)JavaScript的過程中,一定要對(duì)這兩個(gè)函數(shù)有一個(gè)深入的學(xué)習(xí),它們兩個(gè)函數(shù)也是經(jīng)常被使用!
其中,如果分別用一句話來概括這兩個(gè)函數(shù),那么應(yīng)該是這樣的:
setTimeout(): 該函數(shù)能夠按照設(shè)定的時(shí)間值延遲執(zhí)行其中的事件。
setInterval(): 該函數(shù)能夠按照設(shè)定的時(shí)間值作為間隔,周期性的執(zhí)行其中的時(shí)間。
當(dāng)然了,只是簡(jiǎn)述,細(xì)節(jié)方面,我們?cè)谙旅娴牟糠纸o大家做講解。
II. setTimeout()函數(shù)
首先是我們的setTimeout()函數(shù),它的格式是怎么樣的呢:
setTimeout(function,times);
是的,就是這么簡(jiǎn)單的格式,其中,我們需要兩個(gè)參數(shù),分別是一個(gè)函數(shù)和一個(gè)int值,函數(shù)表示延遲一段時(shí)間后要執(zhí)行的函數(shù)體,int值就是我們說的這段時(shí)間,例如我們看這段簡(jiǎn)單的代碼:
setTimeout(function(){
alert("hello,setTimeout()");
}, 1000);運(yùn)行之后,它會(huì)在1s的延遲之后,彈出一個(gè)彈框,其中1000的單位是毫秒!

學(xué)到這里,大家覺得很簡(jiǎn)單,對(duì)嗎?好的,那我給一段代碼,大家猜一下它會(huì)輸出什么:
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
alert(i)
}, 1000)
}哎,有人要說了,簡(jiǎn)單啊,這不是輸出:1 2 3 4 5 嗎?
然而實(shí)際上是這樣的:【點(diǎn)我揭曉】
也就是,它輸出了5 5 5 5 5,所以這是為什么呢?因?yàn)?strong>setTimeout()是一個(gè)異步執(zhí)行函數(shù),說人話就是,它里面的函數(shù)體,并不會(huì)在每一次執(zhí)行的時(shí)候立刻運(yùn)行,而是會(huì)丟進(jìn)執(zhí)行隊(duì)列中,等待"主線任務(wù)"全部完成,才會(huì)執(zhí)行它。
于是在5次for循環(huán)后,i的值是5,傳進(jìn)去,彈出了5個(gè)5。
那么有沒有解法呢?我給大家兩種解法:
1?? 使用關(guān)鍵字let:
for (let i = 1; i <= 5; i++) {
setTimeout(function () {
alert(i)
}, 1000)
}那為啥使用let就可以了呢:
其實(shí)使用let之后,也沒有改變執(zhí)行機(jī)制,仍然是最后執(zhí)行的alert(),但是let可以在每一次把更新的變量i傳進(jìn)函數(shù)體內(nèi),也就是每一次的i加1之后,會(huì)把這個(gè)新值放進(jìn)隊(duì)列中對(duì)應(yīng)的函數(shù)內(nèi),于是就解出了這個(gè)問題。
2?? 定義一個(gè)外部變量:
我們?cè)?strong>外部定義一個(gè)變量,這樣這個(gè)變量每一次會(huì)被放入隊(duì)列中,依舊不改變本身的執(zhí)行機(jī)制:
var j = 1;
for (i = 1; i <= 5; i++) {
setTimeout(function () {
alert(j)
j++;
}, 1000);
}第二種做法,更容易被別人看懂,也更適合做項(xiàng)目時(shí)實(shí)際使用。
III. setInterval()函數(shù)
第二個(gè)函數(shù)setInterval()就沒那么復(fù)雜了,但是它的功能確實(shí)很強(qiáng)大的,我們先看看它的使用格式:
setInterval(function,times);
依舊是兩個(gè)參數(shù),同setTimeout()格式一致,它可以以設(shè)置的times為間隔來循環(huán)重復(fù)function,我們用一個(gè)小例子來測(cè)試一下:
setInterval(function(){
alert('hello,setInterval()');
}, 1000);運(yùn)行之后,每過1秒,就會(huì)彈出一個(gè)彈窗,顯示這段話。
那運(yùn)行之后,我們想當(dāng)然會(huì)有一個(gè)問題,那就是可以在某個(gè)特定的時(shí)機(jī)讓它不再循環(huán)執(zhí)行了嗎?答案是肯定滴,只不過我們需要定義一個(gè)setInterval()函數(shù)的對(duì)象,我們一般取名叫:timer:
var i = 5;
var timer = setInterval(function(){
i --;
if(i < 0){
clearInterval(timer);
}
alert('i');
}, 1000);上面的代碼中,我們給setInterval創(chuàng)建了一個(gè)對(duì)象叫timer,在外部我們定義了另一個(gè)變量i,之后我們每一次執(zhí)行Interval內(nèi)的函數(shù)時(shí),就讓 i-1 ,減到0以下,清除定時(shí)器:
clearInterval(timer對(duì)象);
上面這句話是清除定時(shí)器的代碼,傳入一個(gè)setInterval()函數(shù)的對(duì)象即可。
IV. 新年倒計(jì)時(shí)案例
最后,我們用學(xué)習(xí)的setTimeout()函數(shù)和setInterval()函數(shù)聯(lián)動(dòng)做一個(gè)新年倒計(jì)時(shí)案例吧:
我們想要這樣的效果:
首先,實(shí)現(xiàn)在屏幕上展示60秒倒計(jì)時(shí);
在倒計(jì)時(shí)為0后,彈窗展示新年快樂!
有人看了這個(gè)說明,覺得那么我們的代碼應(yīng)該是這樣的:
var element = document.getElementById("xin-nian")
var clock = 60;
var timer = null;
timer = setInterval(function () {
element.innerHTML = "新年倒計(jì)時(shí):" + clock + " !";
console.log(clock)
clock--;
if (clock < 0) {
clearInterval(timer);
alert("新年快樂!");
}
}, 1000);乍一看,好像沒問題,但實(shí)際運(yùn)行的時(shí)候,由于向html寫入內(nèi)容有一個(gè)小延遲,會(huì)導(dǎo)致最后倒計(jì)時(shí)0這個(gè)數(shù)字沒被寫進(jìn)去就會(huì)彈窗,因此我們要在倒計(jì)時(shí)最后一秒,用setTimeout()做一個(gè)小緩沖:
if (clock < 0) {
clearInterval(timer);
setTimeout(function () {
alert("新年快樂!")
}, 500)
}于是完整的代碼應(yīng)該是這樣的:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新年倒計(jì)時(shí)</title>
<style>
body {
background-image: url(./1.jpg);
}
</style>
</head>
<body>
<h1 id="xin-nian" style="text-align: center;margin-top: 250px;font-size: 50px;"></h1>
<script>
var element = document.getElementById("xin-nian")
var clock = 60;
var timer = null;
timer = setInterval(function () {
element.innerHTML = "新年倒計(jì)時(shí):" + clock + " !";
console.log(clock)
clock--;
if (clock < 0) {
clearInterval(timer);
setTimeout(function () {
alert("新年快樂!")
}, 500)
}
}, 1000);
</script>
</body>
</html>實(shí)現(xiàn)的效果是下面這樣的動(dòng)圖:

總結(jié)
到此這篇關(guān)于JavaScript setTimeout和setInterval的用法與區(qū)別的文章就介紹到這了,更多相關(guān)js setTimeout和setInterval的用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)正則匹配中文標(biāo)點(diǎn)符號(hào)的方法
這篇文章主要介紹了js實(shí)現(xiàn)正則匹配中文標(biāo)點(diǎn)符號(hào)的方法,涉及JavaScript正則匹配與判定的簡(jiǎn)單使用技巧,需要的朋友可以參考下2015-12-12
JavaScript中具名函數(shù)的多種調(diào)用方式總結(jié)
這篇文章主要介紹了JavaScript中具名函數(shù)的多種調(diào)用方式總結(jié),本文總結(jié)了4種方法,需要的朋友可以參考下2014-11-11
JS日期格式化之javascript Date format
這篇文章主要介紹了JS日期格式化之javascript Date format的相關(guān)資料,需要的朋友可以參考下2015-10-10
Bootstrap選項(xiàng)卡學(xué)習(xí)筆記分享
這篇文章主要為大家詳細(xì)介紹了Bootstrap選項(xiàng)卡學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
JavaScript事件循環(huán)及宏任務(wù)微任務(wù)原理解析
這篇文章主要介紹了JavaScript事件循環(huán)及宏任務(wù)微任務(wù)原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
javascript實(shí)現(xiàn)評(píng)分功能
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)評(píng)分功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
JS/jQuery實(shí)現(xiàn)默認(rèn)顯示部分文字點(diǎn)擊按鈕顯示全部?jī)?nèi)容
默認(rèn)顯示部分文字,點(diǎn)擊按鈕顯示全部,類似這樣的功能在一些特殊的地方會(huì)見到吧,下面與大家分享下JS、jQuery如何實(shí)現(xiàn),感興趣的朋友可以參考下哈,希望對(duì)你有所幫助2013-05-05

