首頁 > web前端 > js教程 > Settimeout JavaScript函數:指南示例

Settimeout JavaScript函數:指南示例

尊渡假赌尊渡假赌尊渡假赌
發布: 2025-02-10 14:34:10
原創
782 人瀏覽過

setTimeout JavaScript Function: Guide with Examples

JavaScript 的 setTimeout 函數詳解:實現延遲執行

setTimeout 是 JavaScript 中的原生函數,用於在指定延遲(毫秒)後調用函數或執行代碼片段。這在許多場景下非常有用,例如:在用戶瀏覽頁面一段時間後顯示彈出窗口,或在移除元素懸停效果前添加短暫延遲(防止誤操作)。

關鍵要點:

  • JavaScript 的 setTimeout 函數允許在指定毫秒數的延遲後執行函數或代碼片段,這對於諸如在一定瀏覽時間後顯示彈出窗口之類的任務非常有用。
  • setTimeout 接受函數引用作為第一個參數,該引用可以是函數名稱、引用函數的變量或匿名函數。它也可以執行代碼字符串,但不建議這樣做,因為這樣會降低可讀性、安全性並降低速度。
  • 可以使用匿名函數作為第一個參數,將參數傳遞給 setTimeout 執行的回調函數。但是,在延遲之後列出參數的替代方法與 IE9 及以下版本不兼容。
  • setTimeout 執行的代碼中,this 的值在與調用它的函數不同的執行上下文中運行,這在 this 關鍵字的上下文很重要時可能會導致問題。這可以使用 bind、庫函數或箭頭函數來解決。
  • setTimeout 的返回值是一個數字 ID,可用於結合 clearTimeout 函數取消計時器。

setTimeout 使用示例

以下代碼塊顯示了一個簡單的示例,該示例將在 2 秒(2000 毫秒)的超時後將消息打印到控制台:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登入後複製
登入後複製
登入後複製
登入後複製

為了更詳細地演示這個概念,下面的演示在點擊按鈕兩秒鐘後顯示一個彈出窗口:(請訪問 CodePen 查看演示)

語法

根據 MDN 文檔,setTimeout 的語法如下:

const timeoutID = setTimeout(code);
const timeoutID = setTimeout(code, delay);

const timeoutID = setTimeout(functionRef);
const timeoutID = setTimeout(functionRef, delay);
const timeoutID = setTimeout(functionRef, delay[, arg1, arg2, /* … ,*/ argN])
登入後複製
登入後複製
登入後複製

其中:

  • timeoutID 是一個數字 ID,可與 clearTimeout 結合使用以取消計時器。
  • scope 指的是 Window 接口或 WorkerGlobalScope 接口。
  • functionRef 是計時器到期後要執行的函數。
  • code 是一種替代語法,允許您包含字符串而不是函數,該字符串在計時器到期時進行編譯和執行。
  • delay 是函數調用應延遲的毫秒數。如果省略,則默認為 0。
  • arg1, ..., argN 是傳遞給 functionRef 指定的函數的其他參數。

注意:方括號 [] 表示可選參數。

setTimeoutwindow.setTimeout

您會注意到,有時語法中包含 window.setTimeout。這是為什麼呢?

在瀏覽器中運行代碼時,scope 將指代全局 window 對象。 setTimeoutwindow.setTimeout 指的是同一個函數,唯一的區別是,在第二個語句中,我們將 setTimeout 方法作為 window 對象的屬性來引用。

在我看來,這增加了複雜性,而好處卻微乎其微。如果您定義了另一種 setTimeout 方法,該方法將在作用域鏈中優先找到並返回,那麼您可能還有更大的問題需要擔心。

在本教程中,我將省略 window,但最終,您選擇哪種語法取決於您自己。

setTimeout 方法的使用示例

setTimeout 方法接受函數引用作為第一個參數。

這可以是函數的名稱:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登入後複製
登入後複製
登入後複製
登入後複製

引用函數的變量(函數表達式):

const timeoutID = setTimeout(code);
const timeoutID = setTimeout(code, delay);

const timeoutID = setTimeout(functionRef);
const timeoutID = setTimeout(functionRef, delay);
const timeoutID = setTimeout(functionRef, delay[, arg1, arg2, /* … ,*/ argN])
登入後複製
登入後複製
登入後複製

或者匿名函數:

function greet() {
  alert('Howdy!');
}
setTimeout(greet, 2000);
登入後複製
登入後複製

如上所述,也可以將代碼字符串傳遞給 setTimeout 以供其執行:

const greet = function() {
  alert('Howdy!');
};
setTimeout(greet, 2000);
登入後複製
登入後複製

但是,由於以下原因,不建議這樣做:

  • 難以閱讀(因此難以維護和/或調試)。
  • 它使用隱式 eval,這是一種潛在的安全風險。
  • 它比替代方案慢,因為它必須調用 JS 解釋器。

傳遞參數給 setTimeout

在基本場景中,首選的跨瀏覽器方法是使用匿名函數作為第一個參數將參數傳遞給 setTimeout 執行的回調函數。

在下面的示例中,我們從 animals 數組中選擇一個隨機動物,並將此隨機動物作為參數傳遞給 makeTalk 函數。然後,setTimeout 以一秒的延遲執行 makeTalk 函數:

setTimeout(() => { alert('Howdy!'); }, 2000);
登入後複製
登入後複製

注意:我使用了一個常規函數(getRandom)從數組中返回一個隨機元素。也可以使用箭頭函數將其編寫為函數表達式:

setTimeout('alert("Howdy!");', 2000);
登入後複製
登入後複製

我們將在下一節介紹箭頭函數。這裡有一個包含上述代碼的 CodePen(您需要打開控制台才能查看輸出)。

替代方法

從文章頂部的語法可以看出,傳遞參數給 setTimeout 執行的回調函數還有第二種方法。這涉及在延遲之後列出任何參數。

參考我們之前的示例,這將給我們:

function makeTalk(animal) {
  const noises = {
    cat: 'purr',
    dog: 'woof',
    cow: 'moo',
    pig: 'oink',
  }

  console.log(`A ${animal} goes ${noises[animal]}.`);
}

function getRandom(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

const animals = ['cat', 'dog', 'cow', 'pig'];
const randomAnimal = getRandom(animals);

setTimeout(() => {
  makeTalk(randomAnimal);
}, 1000);
登入後複製
登入後複製

不幸的是,這在 IE9 或以下版本中不起作用,其中參數作為 undefined 傳遞。如果您不幸需要支持 IE9,則 MDN 上提供了一個 polyfill。

this 關鍵字的問題

setTimeout 執行的代碼在其與調用它的函數不同的執行上下文中運行。當 this 關鍵字的上下文很重要時,這會成為問題:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登入後複製
登入後複製
登入後複製
登入後複製

此輸出的原因是,在第一個示例中,this 指向dog 對象,而在第二個示例中,this 指向全局window 對象(它沒有sound 屬性) 。

為了解決這個問題,有各種方法……

顯式設置 this 的值

您可以使用bind 來實現,bind 方法創建一個新函數,當調用該函數時,其this 關鍵字將設置為提供的值(在本例中為dog 對象) 。這將給我們:

const timeoutID = setTimeout(code);
const timeoutID = setTimeout(code, delay);

const timeoutID = setTimeout(functionRef);
const timeoutID = setTimeout(functionRef, delay);
const timeoutID = setTimeout(functionRef, delay[, arg1, arg2, /* … ,*/ argN])
登入後複製
登入後複製
登入後複製

使用庫

許多庫都帶有內置函數來解決此問題。例如,jQuery 的 jQuery.proxy() 方法。它接受一個函數並返回一個新函數,該函數將始終具有特定上下文。在本例中,那將是:

function greet() {
  alert('Howdy!');
}
setTimeout(greet, 2000);
登入後複製
登入後複製

setTimeout 中使用箭頭函數

箭頭函數是在 ES6 中引入的。它們比常規函數的語法短得多:

const greet = function() {
  alert('Howdy!');
};
setTimeout(greet, 2000);
登入後複製
登入後複製

當然,您可以將它們與 setTimeout 一起使用,但是需要注意一點——箭頭函數沒有自己的 this 值。相反,它們使用封閉詞法上下文的 this 值。

使用常規函數:

setTimeout(() => { alert('Howdy!'); }, 2000);
登入後複製
登入後複製

使用箭頭函數:

setTimeout('alert("Howdy!");', 2000);
登入後複製
登入後複製

在第二個示例中,this 指向全局 window 對象(同樣,它沒有 sound 屬性)。

這在將箭頭函數與 setTimeout 一起使用時可能會讓我們陷入困境。之前我們看到瞭如何為 setTimeout 中調用的函數提供正確的 this 值:

function makeTalk(animal) {
  const noises = {
    cat: 'purr',
    dog: 'woof',
    cow: 'moo',
    pig: 'oink',
  }

  console.log(`A ${animal} goes ${noises[animal]}.`);
}

function getRandom(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

const animals = ['cat', 'dog', 'cow', 'pig'];
const randomAnimal = getRandom(animals);

setTimeout(() => {
  makeTalk(randomAnimal);
}, 1000);
登入後複製
登入後複製

當在引入的方法中使用箭頭函數時,這將不起作用,因為箭頭函數沒有它自己的 this 值。該方法仍將記錄 undefined

使用箭頭函數和 setTimeout 編寫更簡潔的代碼

但是,因為箭頭函數沒有自己的 this 值,所以它也可以為我們帶來優勢。

考慮這樣的代碼:

const getRandom = arr => arr[Math.floor(Math.random() * arr.length)];
登入後複製

可以使用箭頭函數更簡潔地重寫它:

setTimeout(makeTalk, 1000, randomAnimal);
登入後複製

如果您想了解箭頭函數的入門知識,請閱讀“ES6 箭頭函數:JavaScript 中簡潔的語法”。

取消計時器

正如我們在文章開頭了解到的那樣,setTimeout 的返回值是一個數字 ID,可與 clearTimeout 函數結合使用以取消計時器:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登入後複製
登入後複製
登入後複製
登入後複製

讓我們看看它的實際效果。在下面的 Pen 中,如果您點擊“開始倒計時”按鈕,倒計時將開始。如果倒計時完成,小貓就贏了。但是,如果您按下“停止倒計時”按鈕,計時器將被停止並重置。 (如果您在倒計時達到零時沒有看到很酷的效果,請使用嵌入底部右側的按鈕重新運行 Pen。)

總結

在本文中,我演示瞭如何使用 setTimeout 來延遲函數的執行。我還展示瞭如何將參數傳遞給 setTimeout,如何在其回調函數內部維護 this 值,以及如何取消計時器。

setTimeout JavaScript 函數的常見問題解答

  • setTimeout 在 JavaScript 中是什麼?

    setTimeout 是 JavaScript 中的內置函數,允許您在指定的延遲(以毫秒為單位)後安排函數或代碼段的執行。

  • setTimeout 如何工作?

    當您調用 setTimeout 函數時,您需要提供兩個參數:要執行的函數或代碼,以及以毫秒為單位的延遲。提供的函數/代碼將添加到隊列中,並在指定的延遲後,它將從隊列移動到調用堆棧以執行。

  • 使用 setTimeout 的替代方法有哪些?

    是的,有替代方法,例如 setInterval,它會以指定的間隔重複執行函數,以及較新的 requestAnimationFrame,它用於更流暢的動畫和更好的瀏覽器性能。

  • 什麼時候不應該使用 setTimeout

    setTimeout 是用於在 JavaScript 中調度異步代碼執行的有用工具,但在某些情況下它可能不是最佳選擇。對於精確的動畫或遊戲,您應該使用 requestAnimationFrame。您不應該嵌套多個 setTimeout 調用;最好使用 Promise 或異步模式。 setTimeout 對小於 10 毫秒的延遲不准確;請考慮替代方案。如果您正在構建實時應用程序(如在線多人遊戲或金融交易平台),請選擇實時技術,如 WebSockets。大型 CPU 密集型任務可能會阻塞事件循環;如果需要,請使用 Web Workers。

  • 我可以取消 setTimeout 操作嗎?

    是的,您可以使用 clearTimeout 函數取消計劃的超時。它將 setTimeout 返回的超時 ID 作為參數。例如:const timeoutId = setTimeout(myFunction, 1000); clearTimeout(timeoutId);

  • setTimeoutsetInterval 之間的區別是什麼?

    setTimeout 將函數安排在指定的延遲後運行一次,而 setInterval 將函數安排在指定的間隔重複運行,直到它被取消或程序停止。

  • 我可以使用 setTimeout 的最小延遲值是多少?

    最小延遲值為 0,這意味著該函數安排在當前線程完成但處理任何掛起的事件之前執行。但是,計時器的實際粒度因不同的瀏覽器和環境而異。某些環境可能不支持小於 10 毫秒的延遲。

  • setTimeout 在 Node.js 中是什麼?

    setTimeout 是 Node.js 的內置函數,用於將給定函數或代碼塊的執行延遲指定的毫秒數。

  • 如何在 Node.js 中使用 setTimeout

    您可以按如下方式使用 setTimeout 函數:setTimeout(callback, delay); 其中 callback 是您希望在指定的毫秒延遲後執行的函數。

  • 在 Node.js 中使用 setTimeout 的最佳實踐有哪些?

    一些最佳實踐包括使用命名函數作為回調函數,優雅地處理錯誤,並了解事件循環的行為以避免意外延遲或阻塞。此外,請考慮使用 setImmediate 在下一個事件循環週期中立即執行。

(請注意,由於輸入文本中包含 CodePen 的鏈接,我無法直接在輸出中呈現 CodePen 的內容。您需要訪問文中提供的鏈接來查看 CodePen 演示。)

以上是Settimeout JavaScript函數:指南示例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板