首頁 >web前端 >js教程 >JavaScript 閉包:初學者指南

JavaScript 閉包:初學者指南

DDD
DDD原創
2025-01-15 12:29:43567瀏覽

閉包是 JavaScript 中強大的重要功能,許多初學者都對此感到困惑。它們負責 JavaScript 的幾個最有用的功能,例如跨函數呼叫儲存狀態和建立私有變數。本部落格試圖透過將閉包分解為簡單的語言並透過實際範例討論其重要性來解釋閉包。

?什麼是閉包?

當一個函數從 JavaScript 中的另一個函數傳回時,它會繼承父函數的作用域。這意味著即使外部函數已完成執行,返回的函數也可以存取外部函數作用域中定義的變數。 閉包是函數及其封閉範圍的組合。
這是一個更簡單的定義:

  • 閉包是一個函數,「記住」來自外部(封閉)函數範圍的變數。
  • 即使外部函數不再執行,內部函數也可以存取這些變數。

?閉包如何運作:一個例子

?沒有閉包的範例

function outer(){
    let counter = 0
    function inner(){
        counter++
        console.log("counter = " + counter)
    }
    inner()
}
outer()
outer() 
/* Output:
counter = 1
counter = 1 */

?帶閉包的範例

function outer(){
    let counter = 0
    function inner(){
        counter++
        console.log("counter = " + counter)
    }
    return inner
}
const fn = outer()
fn()
fn()
/* Output:
counter = 1
counter = 2 */

?閉包的主要特點

  1. 持久記憶體:外部函數作用域中的變數在外部函數退出後很長一段時間內都會被「記住」。
  2. 詞法作用域:閉包基於函數的定義位置,而不是函數的執行位置。
  3. 多個實例:每個閉包實例儲存自己的外部變數副本。

?多個實例的範例:

function counterFunction() {
    let count = 0;

    return function increment() {
        count++;
        return count;
    };
}

const counter1 = counterFunction();
const counter2 = counterFunction();

console.log("counter1 = " + counter1()); // Output: 1
console.log("counter1 = " + counter1()); // Output: 2
console.log("counter2 = " + counter2()); // Output: 1
console.log("counter1 = " + counter1()); // Output: 3
console.log("counter2 = " + counter2()); // Output: 2

這裡,counter1 和 counter2 都有自己獨立的計數變數。

?閉包的實際用途

1️⃣ 資料隱私: 閉包可以隱藏全域範圍內的變量,因此它們僅在特定函數中可用。
?例:

function secretInfo() {
    let secret = "I love JavaScript";
    return {
        getSecret: function() {
            return secret;
        },
        setSecret: function(newSecret) {
            secret = newSecret;
        }
    };
}

const secretObject = secretInfo();
console.log(secretObject.getSecret()); // Output: I love JavaScript
secretObject.setSecret("I love Python too!");
console.log(secretObject.getSecret()); // Output: I love Python too!
secretObject.setSecret("I love PHP too!");
console.log(secretObject.getSecret()); // Output: I love PHP too!
// Attempting to Access secret Directly will not work
console.log(secretObject.secret); // Output: undefined

✍️ 此程式碼如何顯示資料隱私:

  1. 全域作用域保護:變數secret不能直接從全域作用域或程式碼的任何其他部分存取。例如,如果您嘗試 console.log(secretObject.secret),它將傳回 undefined。
  2. 私有狀態維護:閉包的變數secret是私有的,只能使用getSecret和setSecret方法讀取或修改。
  3. 受控存取:程式透過定義函數 getSecret 和 setSecret 來確保對 Secret 變數的有限存取。

2️⃣ 函數工廠: 函數工廠 是一個產生並傳回新函數的函數。它使我們能夠根據輸入參數動態建立自訂功能。
?例:

function outer(){
    let counter = 0
    function inner(){
        counter++
        console.log("counter = " + counter)
    }
    inner()
}
outer()
outer() 
/* Output:
counter = 1
counter = 1 */

✍️ 此程式碼如何展示函數工廠:

  1. 計算函數的工作原理就像工廠,根據輸入(因子)產生專門的乘數函數(雙倍、三倍)。
  2. 每個功能都是唯一且獨立的,但共享相同的核心邏輯。

3️⃣ 事件監聽器: 閉包通常用於回調和事件監聽器中以維護狀態。
?例:

function outer(){
    let counter = 0
    function inner(){
        counter++
        console.log("counter = " + counter)
    }
    return inner
}
const fn = outer()
fn()
fn()
/* Output:
counter = 1
counter = 2 */

✍️ 此程式碼如何展示閉包如何在事件偵聽器中運作:

  1. setupListener 函數建立一個閉包並在其中定義 clickCount 變數。
  2. 事件監聽器函數是一個回調,即使在 setupListener 方法執行完畢後也可以存取 clickCount。
  3. 每次按一下 ID 為「myButton」的按鈕時,事件偵聽器的回呼都會遞增 clickCount 並記錄更新的值。

JavaScript Closures: A Beginner

?結論

閉包是 JavaScript 中的一個基本思想,它允許開發人員建立更模組化、高效和私有的程式碼。了解閉包使您能夠編寫動態函數、維護持久狀態並實現資料封裝。

作為初學者,花時間練習和嘗試閉包。它們一開始可能看起來很困難,但透過實踐範例和用法,您很快就會意識到它們在 JavaScript 程式設計中令人難以置信的力量和多功能性。

是否有任何現實生活中的類比或例子可以幫助您學習閉包?在下面的評論部分分享它們!
快樂編碼! ✨

以上是JavaScript 閉包:初學者指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn