閉包是指在一個函數內部創建另一個函數,並且內部函數可以訪問外部函數的變量、參數以及其他內部函數,即使外部函數已經執行完畢。這種機制使得內部函數保留了對外部作用域的引用,即使外部作用域已經不再活躍。
為什麼閉包重要?
閉包在 JavaScript 中具有重要的用途和價值。它們可以用於創建私有變量、封裝邏輯、避免全局污染等方面。另外,閉包還允許你在函數之外操作局部變量,從而為代碼提供更大的靈活性和可維護性。
JavaScript 閉包的特點
- 閉包可以訪問外部函數的變量,即使外部函數已經返回了。
- 閉包保存外部函數變量的引用,而不是實際的值。
- 每當一個函數在另一個函數中被創建時,就會產生閉包。
JS 閉包的用途
閉包常被用於:
- 封裝 - 內部函數可以訪問外部變量,但外部函數不能訪問內部變量。這提供了封裝和數據私密性。
- 狀態持續 - 閉包可以在函數調用之間保持狀態(例如計數器)。函數的變量在調用之間持續存在。
- 偏函數應用 - 閉包可以用於偏函數應用和柯里化函數。這涉及到創建一個捕獲一些參數但保留其他參數未設置的函數。
JS 閉包的類型
1. 普通閉包
普通閉包是指一個函數內部定義了另一個函數,並且內部函數引用了外部函數的變量。這種情況下,內部函數會捕獲外部函數的變量,並可以在外部函數執行完畢後繼續使用。
var outerVar = 'I am from outer';
function inner() {
console.log(outerVar);
}
return inner;
}
var closureFunction = outer();
closureFunction(); // 輸出:I am from outer
2. 立即調用函數表達式(IIFE)閉包
IIFE 是一種創建閉包的常見模式。通過將函數定義包裹在括號內並立即調用它,你可以創建一個在執行後仍然具有訪問外部作用域的函數。
var privateVar = 'I am private';
return function() {
console.log(privateVar);
};
})();
closureFunction(); // 輸出:I am private
實踐案例:計數器閉包
讓我們通過一個實際案例來進一步理解閉包的應用。考慮一個簡單的計數器,可以通過閉包來實現:
var count = 0;
return function() {
return ++count;
};
}
var counter = createCounter();
console.log(counter()); // 輸出:1
console.log(counter()); // 輸出:2
console.log(counter()); // 輸出:3
互動練習
1.創建一個閉包函數,用於計算累加和。函數初始值為0,每次調用會將參數值累加到內部變量中。參考答案:
var sum = 0;
return function(value) {
sum += value;
return sum;
};
}
var sumCalculator = createSumCalculator();
console.log(sumCalculator(5)); // 輸出:5
console.log(sumCalculator(10)); // 輸出:15
console.log(sumCalculator(2)); // 輸出:17
2.創建一個IIFE閉包,用於生成斐波那契數列的下一個值。斐波那契數列起始為0和1,後續每個數字是前兩個數字之和。參考答案:
var a = 0;
var b = 1;
return function() {
var next = a + b;
a = b;
b = next;
return next;
};
})();
console.log(fibonacciGenerator()); // 輸出:1
console.log(fibonacciGenerator()); // 輸出:2
console.log(fibonacciGenerator()); // 輸出:3
注意事項
- 閉包會導致內存泄漏,因為閉包保留了對外部作用域的引用,導致外部作用域的變量無法被垃圾回收機制釋放。
- 注意使用閉包時的作用域鏈,避免意外引用到不需要的變量。
- 閉包不僅在瀏覽器中有用,在 Node.js 服務器端編程中也經常使用。
通過 API 工具調試後端接口
Apifox 是一個比 Postman 更強大的接口測試工具,Apifox = Postman + Swagger + Mock + JMeter,Apifox 支持調試 http(s)、WebSocket、Socket、gRPC、Dubbo 等協議的接口,並且集成了 IDEA 插件。在後端人員寫完服務接口時,測試階段可以通過 Apifox 來校驗接口的正確性,圖形化界面極大的方便了項目的上線效率。
總結
閉包是 JavaScript 中一個強大且有趣的概念,允許內部函數訪問外部作用域中的變量和數據。通過創建閉包,你可以實現私有性、封裝性以及更高級的編程技巧。瞭解閉包的工作原理並在實際項目中應用它們,將使你的 JavaScript 代碼更加優雅和功能強大。
知識擴展:
- JavaScript(JS)中怎麼遍歷數組?一文講解 JS 遍歷數組的方法
- JavaScript(JS)中怎麼遍歷對象?一文講解 JS 遍歷對象的方法
參考鏈接:
- MDN Web Docs: Closures:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
- JavaScript.info: Closures:https://javascript.info/closure