
- Javascript 基礎教程
- Javascript - 首頁
- JavaScript - 路線圖
- JavaScript - 概述
- JavaScript - 特性
- JavaScript - 啟用
- JavaScript - 位置
- JavaScript - 語法
- JavaScript - Hello World
- JavaScript - Console.log()
- JavaScript - 註釋
- JavaScript - 變數
- JavaScript - let 語句
- JavaScript - 常量
- JavaScript - 資料型別
- JavaScript - 型別轉換
- JavaScript - 嚴格模式
- JavaScript - 保留關鍵字
- JavaScript 運算子
- JavaScript - 運算子
- JavaScript - 算術運算子
- JavaScript - 比較運算子
- JavaScript - 邏輯運算子
- JavaScript - 位運算子
- JavaScript - 賦值運算子
- JavaScript - 條件運算子
- JavaScript - typeof 運算子
- JavaScript - 空值合併運算子
- JavaScript - delete 運算子
- JavaScript - 逗號運算子
- JavaScript - 分組運算子
- JavaScript - yield 運算子
- JavaScript - 展開運算子
- JavaScript - 指數運算子
- JavaScript - 運算子優先順序
- JavaScript 控制流
- JavaScript - If...Else
- JavaScript - While 迴圈
- JavaScript - For 迴圈
- JavaScript - For...in
- Javascript - For...of
- JavaScript - 迴圈控制
- JavaScript - Break 語句
- JavaScript - Continue 語句
- JavaScript - Switch Case
- JavaScript - 使用者定義迭代器
- JavaScript 函式
- JavaScript - 函式
- JavaScript - 函式表示式
- JavaScript - 函式引數
- JavaScript - 預設引數
- JavaScript - Function() 建構函式
- JavaScript - 函式提升
- JavaScript - 自執行函式
- JavaScript - 箭頭函式
- JavaScript - 函式呼叫
- JavaScript - Function call()
- JavaScript - Function apply()
- JavaScript - Function bind()
- JavaScript - 閉包
- JavaScript - 變數作用域
- JavaScript - 全域性變數
- JavaScript - 智慧函式引數
- JavaScript 物件
- JavaScript - Number
- JavaScript - Boolean
- JavaScript - Strings
- JavaScript - Arrays
- JavaScript - Date
- JavaScript - DataView
- JavaScript - Handler
- JavaScript - Math
- JavaScript - RegExp
- JavaScript - Symbol
- JavaScript - Sets
- JavaScript - WeakSet
- JavaScript - Maps
- JavaScript - WeakMap
- JavaScript - 可迭代物件
- JavaScript - Reflect
- JavaScript - TypedArray
- JavaScript - 模板字面量
- JavaScript - 帶標籤的模板
- 面向物件 JavaScript
- JavaScript - 物件
- JavaScript - 類
- JavaScript - 物件屬性
- JavaScript - 物件方法
- JavaScript - 靜態方法
- JavaScript - 顯示物件
- JavaScript - 物件訪問器
- JavaScript - 物件建構函式
- JavaScript - 原生原型
- JavaScript - ES5 物件方法
- JavaScript - 封裝
- JavaScript - 繼承
- JavaScript - 抽象
- JavaScript - 多型
- JavaScript - 解構賦值
- JavaScript - 物件解構
- JavaScript - 陣列解構
- JavaScript - 巢狀解構
- JavaScript - 可選鏈
- JavaScript - 全域性物件
- JavaScript - Mixins
- JavaScript - 代理
- JavaScript 版本
- JavaScript - 歷史
- JavaScript - 版本
- JavaScript - ES5
- JavaScript - ES6
- ECMAScript 2016
- ECMAScript 2017
- ECMAScript 2018
- ECMAScript 2019
- ECMAScript 2020
- ECMAScript 2021
- ECMAScript 2022
- JavaScript 非同步
- JavaScript - 非同步
- JavaScript - 回撥函式
- JavaScript - Promises
- JavaScript - Async/Await
- JavaScript - 微任務
- JavaScript - Promise 化
- JavaScript - Promises 鏈式呼叫
- JavaScript - 定時事件
- JavaScript - setTimeout()
- JavaScript - setInterval()
- JavaScript Cookies
- JavaScript - Cookies
- JavaScript - Cookie 屬性
- JavaScript - 刪除 Cookies
- JavaScript 瀏覽器 BOM
- JavaScript - 瀏覽器物件模型
- JavaScript - Window 物件
- JavaScript - Document 物件
- JavaScript - Screen 物件
- JavaScript - History 物件
- JavaScript - Navigator 物件
- JavaScript - Location 物件
- JavaScript - Console 物件
- JavaScript Web APIs
- JavaScript - Web API
- JavaScript - History API
- JavaScript - Storage API
- JavaScript - Forms API
- JavaScript - Worker API
- JavaScript - Fetch API
- JavaScript - Geolocation API
- JavaScript 事件
- JavaScript - 事件
- JavaScript - DOM 事件
- JavaScript - addEventListener()
- JavaScript - 滑鼠事件
- JavaScript - 鍵盤事件
- JavaScript - 表單事件
- JavaScript - Window/Document 事件
- JavaScript - 事件委託
- JavaScript - 事件冒泡
- JavaScript - 事件捕獲
- JavaScript - 自定義事件
- JavaScript 錯誤處理
- JavaScript - 錯誤處理
- JavaScript - try...catch
- JavaScript - 除錯
- JavaScript - 自定義錯誤
- JavaScript - 擴充套件錯誤
- JavaScript 重要關鍵字
- JavaScript - this 關鍵字
- JavaScript - void 關鍵字
- JavaScript - new 關鍵字
- JavaScript - var 關鍵字
- JavaScript HTML DOM
- JavaScript - HTML DOM
- JavaScript - DOM 方法和屬性
- JavaScript - DOM Document
- JavaScript - DOM 元素
- JavaScript - DOM 屬性 (Attr)
- JavaScript - DOM 表單
- JavaScript - 更改 HTML
- JavaScript - 更改 CSS
- JavaScript - DOM 動畫
- JavaScript - DOM 導航
- JavaScript - DOM 集合
- JavaScript - DOM NodeList
- JavaScript - DOM DOMTokenList
- JavaScript 雜項
- JavaScript - Ajax
- JavaScript - 非同步迭代
- JavaScript - Atomics 物件
- JavaScript - Rest 引數
- JavaScript - 頁面重定向
- JavaScript - 對話方塊
- JavaScript - 頁面列印
- JavaScript - 驗證
- JavaScript - 動畫
- JavaScript - 多媒體
- JavaScript - 影像地圖
- JavaScript - 瀏覽器
- JavaScript - JSON
- JavaScript - 多行字串
- JavaScript - 日期格式
- JavaScript - 獲取日期方法
- JavaScript - 設定日期方法
- JavaScript - 模組
- JavaScript - 動態匯入
- JavaScript - BigInt
- JavaScript - Blob
- JavaScript - Unicode
- JavaScript - 淺複製
- JavaScript - 呼叫棧
- JavaScript - 引用型別
- JavaScript - IndexedDB
- JavaScript - 點選劫持攻擊
- JavaScript - 柯里化
- JavaScript - 圖形
- JavaScript - Canvas
- JavaScript - 防抖
- JavaScript - 效能
- JavaScript - 樣式指南
JavaScript - 回撥函式
什麼是回撥函式?
JavaScript 中的回撥函式通常作為另一個函式的引數傳遞。不要將“回撥”視為此處名稱或關鍵字。“回撥”函式名稱可以是任何有效的識別符號。
回撥函式可以在父函式完成父函式中的特定任務後在父函式內部被呼叫。它主要用於處理非同步操作。
語法
您可以按照以下語法使用回撥函式。
function func_name(callback) { // function body callback(); } func_name(callback); // Function invocation OR func_name(() => { // Callback function body })
在上述語法中,我們將“callback”作為 func_name() 函式的引數傳遞。
如上述語法所示,您還可以將箭頭函式或匿名函式作為回撥函式傳遞。
示例
在下面的程式碼中,我們將 multiply() 函式作為 sum() 函式的引數傳遞。
在 sum() 函式中,我們在最後呼叫回撥函式。
<html> <body> <div id = "output"> </div> <script> let output = document.getElementById('output'); function multiply(a) { let m = a * 4; output.innerHTML = "The result is " + m + ".<br>"; } function sum(a, b, callback) { let c = a + b; callback(c); // Invoking the callback funciton } sum(4, 8, multiply); // Passing multiply function as a callback </script> </body> </html>
輸出
The result is 48.
將匿名函式作為回撥傳遞
示例
在下面的程式碼中,我們定義了 mathOperations() 函式,該函式將回調函式作為引數。
我們在 mathOperations() 函式內部呼叫回撥函式並獲取其返回值。
在呼叫 mathOperations() 函式時,我們傳遞了不同的匿名函式作為引數。這樣,您可以使用回撥函式控制要在特定函式內部執行的函式。
<html> <body> <div id = "output"> </div> <script> let output = document.getElementById('output'); function mathOperation(a, b, callback) { let result = callback(a, b); output.innerHTML += "The result is " + result + ".<br>"; } mathOperation(10, 20, function (a, b) { return a + b; // Callback function to add numbers }); mathOperation(20, 10, function (a, b) { return a - b; // Callback function to subtract numbers }); mathOperation(10, 20, function (a, b) { return a * b; // Callback function to multiply numbers }); </script> </body> </html>
輸出
The result is 30. The result is 10. The result is 200.
回撥函式的必要性
現在,讓我們瞭解回撥函式在即時開發中的必要性。
JavaScript 是一種單執行緒程式語言。因此,它逐行執行程式碼。當您需要從 API 獲取資料、載入影像或執行任何非同步操作時,它可能需要時間並阻塞其他程式碼的執行。
在這種情況下,您可以使用回撥函式來執行必須在非同步操作之後執行的程式碼,並且您可以執行其他程式碼而不會阻塞它。
例如,您正在發出 API 請求,並且需要 API 資料用於驗證目的。因此,您可以在回撥函式中執行資料驗證並繼續執行其他任務。
讓我們使用 setTimeOut() 方法來理解它。
示例
在下面的程式碼中,我們使用 setTimeOut() 方法編寫非同步程式碼。
它在延遲 500 毫秒後執行 printMessage() 函式。我們將 printMessage() 函式作為 setTimeOut() 方法的回撥傳遞。
在輸出中,您可以觀察到指令碼在沒有阻塞的情況下執行,並且它在 500 毫秒後執行 printMessage() 函式。
<html> <body> <div id = "output"> </div> <script> let output = document.getElementById('output'); output.innerHTML += "Start of the program. <br>"; setTimeout(printMessage, 500); // Asynchronous code function printMessage() { output.innerHTML += "In the printMessage() function. <br>"; } output.innerHTML += "End of the program. <br>"; </script> </body> </html>
輸出
Start of the program. End of the program. In the printMessage() function.
帶有內建方法的回撥函式
許多內建 JavaScript 方法將回調函式作為引數,以在方法執行完成後執行自定義 JavaScript 程式碼。
在這裡,我們將檢視 2 到 3 個內建方法,這些方法將回調函式作為引數並附帶示例。
帶有回撥函式的 JavaScript array.sort() 方法
array.sort() 方法用於對陣列元素進行排序。預設情況下,它按升序對陣列元素進行排序。如果要按降序或任何自定義順序對陣列元素進行排序,則可以將回調函式作為引數傳遞。
語法
請按照以下語法使用 array.sort() 方法
arr.sort(callback);
array.sort() 方法可以選擇性地將回調函式作為引數。回撥函式應返回 0、1 或 -1。
示例
在下面的程式碼中,我們定義了包含數字值的陣列。首先,我們使用了沒有回撥函式的 sort() 方法。您可以看到它按升序對陣列進行排序。
之後,我們將匿名函式作為 sort() 方法的回撥函式傳遞。回撥函式返回元素 b 和 a 之間的差值,以便按降序對陣列進行排序。
<html> <body> <div id = "output"> </div> <script> let output = document.getElementById('output'); let arr = [23, 21, 56, 11, 10, 7, 8]; output.innerHTML += "The sorted array is - " + arr.sort(); // Sorting array in descending order let sorted = arr.sort(function (a, b) { return b - a; }); output.innerHTML += "<br>The sorted array in descending order is - " + sorted; </script> </body> </html>
輸出
The sorted array is - 10,11,21,23,56,7,8 The sorted array in descending order is - 56,23,21,11,10,8,7
帶有回撥函式的 JavaScript array.filter() 方法
array.filter()
方法用於過濾陣列元素。它接收一個回撥函式作為引數。如果回撥函式返回 true
,則過濾該元素。否則,跳過該陣列元素。
語法
請按照以下語法使用 array.filter()
方法。
Array.filter(callback);
回撥函式必須返回布林值。
示例
在下面的程式碼中,我們將 filterCallback()
函式作為 filter()
方法的回撥函式傳遞。如果數字為偶數,則 filterCallback()
函式返回布林值。
最後,您可以在輸出中看到過濾後的偶數。
<html> <body> <div id = "output"> </div> <script> let output = document.getElementById('output'); let arr = [23, 21, 56, 11, 10, 7, 8]; let eventNums = arr.filter(filtercallback); function filtercallback(element) { return element % 2 == 0; } output.innerHTML += "The original array is: " + arr + "<br>"; output.innerHTML += "The even numbers are: " + eventNums; </script> </body> </html>
輸出
The original array is: 23,21,56,11,10,7,8 The even numbers are: 56,10,8
帶有事件的回撥函式
您可以在 JavaScript 中使用 addEventListner()
方法來監聽事件。addEventListener()
方法將回調函式作為第二個引數。
每當網頁上觸發指定的事件時,它都會執行回撥函式。
語法
請按照以下語法使用 addEventListener()
方法。
Element.addEventListener(event, callback);
在上面的語法中,event
是一個表示事件名稱的字串,callback
是一個在事件觸發時應執行的函式。
示例
在下面的程式碼中,我們建立了一個按鈕。
在 JavaScript 中,我們使用其 ID 訪問了按鈕並添加了點選事件。
每當使用者點選按鈕時,它都會列印訊息。
<html> <body> <button id = "btn"> Click Me </button> <p id = "output"> </p> <script> let output = document.getElementById('output'); let button = document.getElementById('btn'); button.addEventListener('click', function () { output.innerHTML = 'You have clicked the button. <br>'; }); </script> </body> </html>
輸出

巢狀回撥和回撥地獄
您可以像 JavaScript 中的巢狀迴圈或 if-else 語句一樣擁有巢狀回撥函式。如果第一個函式依賴於第二個函式的資料,而第二個函式依賴於第三個函式的資料,則您可能需要巢狀回撥函式。
讓我們透過下面的示例來理解它。
示例
asyncTask()
函式在下面的程式碼中完成任務並呼叫作為引數傳遞的回撥函式。
之後,我們呼叫了 asyncTask()
函式並將回撥函式作為第三個引數傳遞。在回撥函式中,我們再次呼叫了 asyncTask()
函式並將回撥函式作為第三個引數傳遞。
這樣,我們在 3 個巢狀級別使用了回撥函式。
<html> <body> <div id = "output"> </div> <script> let output = document.getElementById('output'); function asyncTask(taskName, duration, callback) { output.innerHTML += "Task started " + taskName + "<br/>" setTimeout(() => { output.innerHTML += 'Completed ' + taskName + '<br/>'; callback(); }, duration); } // Task 1 asyncTask('Task 1', 1000, () => { // Task 2 asyncTask('Task 2', 1500, () => { // Task 3 asyncTask('Task 3', 1000, () => { output.innerHTML += "All tasks completed"; }); }); }); </script> </body> </html>
輸出
Task started Task 1 Completed Task 1 Task started Task 2 Completed Task 2 Task started Task 3 Completed Task 3 All tasks completed
由於其巢狀回撥的複雜語法,它也被稱為回撥地獄。
每當您需要使用巢狀回撥函式時,可以使用 Promise 或 async/await 來編寫更簡單的程式碼。
在接下來的章節中,您將學習 Promise 和 async/await 來處理非同步操作。