概念
闭包 是能访问其自身函数作用域外变量的函数
本质 = 函数 + 其词法环境
例子
🌰1(全局环境闭包):
js
let a = 7;
function sum(b){
return a + b
}
const sixSum = sum(6)
console.log(sixSum)
在定义 sum
时,JS引擎将其与当前词法环境(含 a
)绑定为闭包 即
css
闭包 = {
函数: sum (...) { ... }, // 函数本身
环境: { // 精确捕获的被引用变量
a: 7,
}
}
🌰2(嵌套函数闭包):
js
function outer(){
let a = 7
return function inner(){
a++
console.log(a);
}
}
let outerOne = outer()
outerOne()
在定义 sum
时,JS引擎将其与当前词法环境(含 a
)绑定为闭包 即
css
闭包 = {
函数: inner (...) { ... }, // 函数本身
环境: { // 精确捕获的被引用变量
a: 7,
}
}
- 闭包仅保存被引用的变量 (
a
),不会保存整个函数体 - 每次调用
outer()
创建独立闭包环境
实际应用场景
① 封装私有变量
javascript
function createCounter() {
let count = 0; // 私有变量
return {
increment: () => { count++; },
getValue: () => count
};
}
const counter = createCounter();
counter.increment();
console.log(counter.getValue()); // 1
// 无法直接访问 count,只能通过闭包暴露的方法操作
② 模块化开发(IIFE模式)
javascript
const module = (() => {
let privateVar = 'secret';
const privateMethod = () => console.log(privateVar);
return { publicMethod: privateMethod };
})();
module.publicMethod(); // 输出 "secret"
③ 回调函数与事件处理
javascript
function setupClickHandler(buttonId) {
const button = document.getElementById(buttonId);
let clickCount = 0;
button.addEventListener('click', () => {
clickCount++;
console.log(`按钮点击次数:${clickCount}`);
});
}
// 即使 setupClickHandler 执行完毕,回调函数仍能通过闭包访问 clickCount
④ 函数工厂(参数预置)
javascript
function createMultiplier(x) {
return function(y) { // 闭包记忆x的值
return x * y
}
}
const double = createMultiplier(2);
console.log(double(5)); // 10 x=2通过闭包保存