JavaScript闭包
闭包
闭包 = 外部变量 + 内部函数,本来随着外层函数的使用完毕,
外层函数内部的变量应该随之被销毁,但是因为被return出去
的内部函数使用到了外层函数的变量,且交给了第三者,使得
第三者可以通过内部函数获取到外层函数的变量
function A(){
let tname = "tt";
return function(){
console.log(tname);
}
}
const B = A();
B();//tt
//使用完毕之后记得销毁
B=null;

2026-06-01 15:14
问题: 闭包会造成内存泄漏,所以使用完毕后需要手动释放
作用: 统计函数使用次数、函数柯里化、节流、防抖、私有变量、循环setTimeout
- 统计函数调用次数
function counter() {
let count = 0;
return function() {
count++;
console.log(`调用了${count}次`);
}
}
const fn = counter();
fn(); // 1次
fn(); // 2次
fn(); // 3次
fn = null; // 销毁
- 函数柯里化
function add(a) {
return function(b) {
return a + b;
}
}
const add5 = add(5);
add5(3); // 8
add5(7); // 15
核心: 把多参数函数拆成单参数函数,参数分步传入。
- 防抖(输入框搜索)
function debounce(fn, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
}
}
const search = debounce(() => console.log('搜索'), 500);
input.addEventListener('input', search);
核心: 每次触发先把上一个定时器清掉,只执行最后一次。
- 节流(滚动加载)
function throttle(fn, interval) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) {
fn.apply(this, args);
lastTime = now;
}
}
}
const scrollLoad = throttle(() => console.log('加载更多'), 1000);
window.addEventListener('scroll', scrollLoad);
核心: 记录上次执行时间,间隔不够就不执行。
- 私有变量(模块模式)
const user = (function() {
let name = 'Tom'; // 私有变量,外部无法直接访问
return {
getName() { return name; },
setName(n) { name = n; }
}
})();
user.getName(); // 'Tom'
user.setName('Jerry');
user.getName(); // 'Jerry'
user.name; // undefined,无法直接访问
核心: 通过闭包隐藏内部状态,只暴露操作方法。
- 循环中的
setTimeout
// 用闭包保留每次的 i
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(() => console.log(j), 100);
})(i);
}
// 更简单的实现:用 let(块级作用域)
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100);
}
2026/6/28 11:52

浙公网安备 33010602011771号