JavaScript 入門:閉包 Closure 是什麼?

更新 發佈閱讀 6 分鐘

閉包是什麼

一個函式可以記住存取它被宣告時所在的詞彙環境(Lexical environment)中的變數,即使外層函式已經執行完畢。

換句話說就是:閉包 = 函式 + 這個函式建立時所在的詞法環境。


詞法作用域 Lexical Scope

作用域在 【JavaScript 入門:作用域 Scope 和作用域鏈 Scope chain】文章中有介紹過,這邊簡單再提一下:作用域指的是「變數或函式可以被存取的範圍」。

在 JavaScript 中,作用域分成三種:

  • 全域作用域(Global Scope)
  • 函式作用域(Function Scope)
  • 區塊作用域(Block Scope)

詞法作用域 又是甚麼? 詞法作用域也被稱為靜態作用域 (Static Scope),指的是:

變數能不能被存取」是在宣告時決定,而非執行時決定。

詞法作用域說明範例:

let name = "小明";

function sayHi(){
console.log(name);
}
function greeting(){
let name = "小美";
sayHi();
}
greeting();

這段程式的輸出會是什麼呢? 答案是 "小明"。因為詞法作用域的規則是:函式在哪定義,就會在哪找變數,跟執行的地方無關。

  1. 在定義階段,sayHi 在全域環境裡,同時這裡有一個 let name = 小明sayHi 就記住了這個詞法環境。
  2. 執行 greeting() 時,雖然 greeting 裡宣告了 let name = 小美,但這是 greeting 內部的變數。
  3. 執行 sayHi ​時,函式會在被宣告的地方找變數,找到的 name 就是存著"小明" 的全域變數 。

這就是詞法作用域的概念,其實從這個例子和文章開頭的閉包簡介,應該可以稍微聯想到,我們甚至可以把閉包當作靜態作用域的產物。


閉包範例

直接以上面的程式碼來做修改:

function greeting(){
let name = "小美";
return function hey(){
console.log(name);
};
}
const sayHi = greeting();
sayHi();

這個例子中,我們用 sayHi() 來儲存 greeting() 的返回值 hey(),當執行 sayHi()時,雖然 greeting() 已經結束,但是回傳的函式記住了被定義時外層的 let name = "小美",因此執行時可以印出 "小美"。


再看一個複雜一點的範例,但概念都是一樣的。下方以一個密碼管理的程式為範例;

function passwordManager(initialPassword){
let password = initialPassword; // 將傳入的參數作為初始的密碼

return{ // 返回一個包含兩個函式的物件
setPassword:function(newPassword){
password = newPassword;
console.log("密碼設定成功!");
},
checkPassword:function(input){
let res = (input === password)?"正確":"錯誤";
console.log(`密碼${res}`);
}
};
}
const passwordManagerInstance = passwordManager(1234); // 初始化一個密碼管理器,並設定初始密碼為 1234
passwordManagerInstance .checkPassword(2345); // 使用回傳的函式檢查密碼,會輸出"密碼錯誤"
passwordManagerInstance .setPassword(2345); // 修改密碼
passwordManagerInstance .checkPassword(2345); // 再次使用回傳的函式檢查密碼,會輸出"密碼正確"
  1. passwordManager() 被執行
  2. passwordManager() 回傳了包含 setPassword() 函式與 checkPassword() 函式的物件
  3. passwordManager() 執行結束
  4. setPassword()checkPassword() ​記住了被宣告時外層的變數 password
  5. password被「關在」setPassword()checkPassword() 的共同詞法環境裡 → 這就是閉包

📌 重點:

只要詞法環境仍被函式引用,該環境就不會被Javascript 的回收機制收掉,被閉包關注的變數就能繼續存活。所以 password沒有消失,是因為還有人(setPassword/checkPassword)在使用。


總結

這篇文章中簡單介紹了閉包的概念,也給了幾個範例,最後用一句話總結閉包:

函式 + 這個函式建立時所在的詞法環境。這讓內部函式即使在外部函式結束後,仍可以存取並記住定義在外層的變數。


參考

  1. 什麼是閉包 (Closure)?
  2. 閉包
留言
avatar-img
Elaine 粼粼的林林總總
6會員
21內容數
不定期地分享程式/旅遊/學習/閱讀或各式各樣的文章,如果對我的分享有興趣,歡迎來找我玩~
2026/02/05
開發 JavaScript 程式時,了解作用域的概念是非常重要的事情。本篇文章介紹了 JS 的三種作用域:全域作用域、函式作用域、區塊作用域以及作用域鏈的概念。
2026/02/05
開發 JavaScript 程式時,了解作用域的概念是非常重要的事情。本篇文章介紹了 JS 的三種作用域:全域作用域、函式作用域、區塊作用域以及作用域鏈的概念。
2026/02/04
為什麼 JavaScript 中的字串無法修改?為什麼複製變數後,改變其中一個會影響另一個?本文將深入解析 JavaScript 的原生值 (primitive values) 與物件 (objects) 的運作機制,說明傳值與傳參考的差異,避免非預期的程式行為,提升開發效率!!
Thumbnail
2026/02/04
為什麼 JavaScript 中的字串無法修改?為什麼複製變數後,改變其中一個會影響另一個?本文將深入解析 JavaScript 的原生值 (primitive values) 與物件 (objects) 的運作機制,說明傳值與傳參考的差異,避免非預期的程式行為,提升開發效率!!
Thumbnail
2026/02/03
Javascript 中有三種宣告的保留字:var、let、const,這三種宣告方式究竟差在哪裡呢?
Thumbnail
2026/02/03
Javascript 中有三種宣告的保留字:var、let、const,這三種宣告方式究竟差在哪裡呢?
Thumbnail
看更多
你可能也想看
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
現代 JavaScript 教學:從語法到實戰應用,涵蓋陣列方法(map, forEach, reduce)、物件解構、原型鏈與 Class、React 基礎(函數組件、useState)、JavaScript 引擎簡介及商業應用案例。教學包含圖解、範例及常見錯誤比較,幫助讀者快速上手。
Thumbnail
現代 JavaScript 教學:從語法到實戰應用,涵蓋陣列方法(map, forEach, reduce)、物件解構、原型鏈與 Class、React 基礎(函數組件、useState)、JavaScript 引擎簡介及商業應用案例。教學包含圖解、範例及常見錯誤比較,幫助讀者快速上手。
Thumbnail
這篇開始進到跟網頁互動較密切相關的單元,我會學習DOM 跟常用的網頁設計指令。練的環境是 VS code,之前的環境是Colab,但Colab比較適合Python。 DOM(Document Object Model),文件物件模型 DOM 是瀏覽器幫你把 網頁HTML 變成 JavaScrip
Thumbnail
這篇開始進到跟網頁互動較密切相關的單元,我會學習DOM 跟常用的網頁設計指令。練的環境是 VS code,之前的環境是Colab,但Colab比較適合Python。 DOM(Document Object Model),文件物件模型 DOM 是瀏覽器幫你把 網頁HTML 變成 JavaScrip
Thumbnail
本系列文章將循序漸進地介紹 JavaScript 的核心概念,從基礎語法到進階應用,例如非同步程式設計和 React 基礎。內容淺顯易懂,並使用生活化的比喻幫助讀者理解,搭配程式碼範例,適合 JavaScript 初學者學習。
Thumbnail
本系列文章將循序漸進地介紹 JavaScript 的核心概念,從基礎語法到進階應用,例如非同步程式設計和 React 基礎。內容淺顯易懂,並使用生活化的比喻幫助讀者理解,搭配程式碼範例,適合 JavaScript 初學者學習。
Thumbnail
閉包是指一個函數能夠「記住」它被創建時的外部環境(作用域),即使那個外部環境已經不存在了。 簡單來說,閉包就像是函數帶著一個「記憶背包」,裡面裝著它出生時能看到的變數。
Thumbnail
閉包是指一個函數能夠「記住」它被創建時的外部環境(作用域),即使那個外部環境已經不存在了。 簡單來說,閉包就像是函數帶著一個「記憶背包」,裡面裝著它出生時能看到的變數。
Thumbnail
什麼是執行環境(Execution Context)? 簡單來說,執行環境是 JavaScript 程式碼執行時所在的「環境」。 它決定了程式碼如何被解析和執行,並管理變數、函數以及作用域(scope)的存取。 每當程式碼執行時,JavaScript 引擎會建立一個執行環境。
Thumbnail
什麼是執行環境(Execution Context)? 簡單來說,執行環境是 JavaScript 程式碼執行時所在的「環境」。 它決定了程式碼如何被解析和執行,並管理變數、函數以及作用域(scope)的存取。 每當程式碼執行時,JavaScript 引擎會建立一個執行環境。
Thumbnail
簡介 本篇教學將帶您使用 Node.js 和 JavaScript 實現一個簡易相簿功能,具備圖片上傳、顯示以及查看原圖的功能。我們將利用 Express 框架以及 multer 中介軟體處理文件上傳,並使用 EJS 作為模板引擎來呈現網頁內容。 實現目標 相簿首頁:顯示所有已上傳的圖片。
Thumbnail
簡介 本篇教學將帶您使用 Node.js 和 JavaScript 實現一個簡易相簿功能,具備圖片上傳、顯示以及查看原圖的功能。我們將利用 Express 框架以及 multer 中介軟體處理文件上傳,並使用 EJS 作為模板引擎來呈現網頁內容。 實現目標 相簿首頁:顯示所有已上傳的圖片。
Thumbnail
檔案上傳是許多網站的核心功能,無論是上傳圖片、文件,甚至是大型的資料檔案。本文將教您如何使用 JavaScript 與 Node.js 搭配 Express 與 Multer 套件,實現檔案上傳功能,並將檔案儲存至伺服器指定的目錄中。
Thumbnail
檔案上傳是許多網站的核心功能,無論是上傳圖片、文件,甚至是大型的資料檔案。本文將教您如何使用 JavaScript 與 Node.js 搭配 Express 與 Multer 套件,實現檔案上傳功能,並將檔案儲存至伺服器指定的目錄中。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News