什么是闭包?你说说他的应用场景?
...大约 3 分钟
1.📝 闭包面试速记(三层结构)
1️⃣ 闭包的本质(核心定义)
不是简单的函数套函数,而是函数 + 其词法环境的组合。
当内部函数被外部引用时,会带走外部函数的执行上下文,让外部函数的变量不会被垃圾回收,这是闭包的核心。
2️⃣ 高频应用场景(面试必问)
防抖 / 节流:利用闭包保存
timer变量,每次调用都能访问上一次的计时器,实现延迟执行。循环绑定事件:解决
var没有块级作用域的问题,用立即执行函数(IIFE)保存每次循环的变量值。模块化封装:私有化变量,避免全局污染,实现函数颗粒化,只暴露需要的 API。
3️⃣ 避坑与内存管理
误区纠正:闭包 ≠ 内存泄漏,只有闭包函数被长期引用时,才会导致泄漏。
解决方法:
- 用完手动把闭包引用置为
null,释放引用。- 避免用闭包存储大对象。
- 使用
WeakMap/WeakSet弱引用,让对象可以被自动回收。
- 用完手动把闭包引用置为
2.📝 闭包面试 30 秒口述版 + 手写示例
一、30 秒口述速记(面试直接背)
闭包本质是函数 + 词法环境的组合,核心是内部函数被外部引用时,会保留外部函数的执行上下文,让变量不被垃圾回收。
常见场景有三个:
防抖节流,用闭包保存定时器变量;
循环绑定事件,解决 var 无块级作用域的问题;
模块化封装,实现变量私有化,避免全局污染。
注意闭包不等于内存泄漏,只要不用长期引用、不存大对象,或者手动置为 null,就可以避免。
二、手写闭包经典示例(防抖 + 模块化)
防抖(闭包最典型应用)
javascript
运行
// 利用闭包实现私有变量,避免全局污染
const counter = (function() {
// 私有变量,外部无法直接访问
let count = 0;
return {
add() {
count++;
console.log(count);
},
reset() {
count = 0;
console.log(count);
}
};
})();
counter.add(); // 输出1
counter.add(); // 输出2
counter.reset(); // 输出0
console.log(counter.count); // undefined(外部无法访问)模块化封装(变量私有化)
javascript
运行
// 利用闭包实现私有变量,避免全局污染
const counter = (function() {
// 私有变量,外部无法直接访问
let count = 0;
return {
add() {
count++;
console.log(count);
},
reset() {
count = 0;
console.log(count);
}
};
})();
counter.add(); // 输出1
counter.add(); // 输出2
counter.reset(); // 输出0
console.log(counter.count); // undefined(外部无法访问)三、面试加分项:闭包与内存泄漏避坑说明
闭包本身不会造成内存泄漏,只有闭包函数被长期持有引用时,外部函数的上下文才会一直不被回收,才会导致泄漏。
解决方法:
用完后手动释放引用:
debouncedFn = null;避免在闭包中存储大对象 / 长生命周期数据
用
WeakMap/WeakSet存对象引用,让 GC 可以自动回收
图



赞助





