什么是闭包

什么是闭包

闭包定义

在JavaScript中,内层函数引用外层函数作用域的变量/函数,且内层函数被外部访问,导致外层函数执行完后,其作用域不会被销毁,这种"函数+其关联的作用域"组合称为闭包。

核心特征:

  • 延长变量的生命周期;
  • 私有化变量(避免全局污染)。

核心示例

javascript 复制代码
function outer() {
  const privateVar = '私有变量'; // 外层函数变量
  // 内层函数引用外层变量
  function inner() {
    console.log(privateVar);
  }
  return inner; // 内层函数被外部访问
}

const fn = outer(); 
fn(); // 输出:私有变量(outer执行完后,privateVar仍被保留)

适用场景

  1. 私有化变量/方法:模拟类的私有属性(JavaScript无原生私有属性)。
javascript 复制代码
const Counter = (() => {
  let count = 0; // 私有变量,外部无法直接访问
  return {
    increment: () => count++,
    decrement: () => count--,
    getCount: () => count
  };
})();
Counter.increment();
console.log(Counter.getCount()); // 1
console.log(Counter.count); // undefined(无法直接访问)
  1. 缓存数据:如计算结果缓存(避免重复计算)。
javascript 复制代码
function createCalculator() {
  const cache = {}; // 缓存计算结果
  return {
    add: (a, b) => {
      const key = `${a}+${b}`;
      if (cache[key]) return cache[key];
      const result = a + b;
      cache[key] = result;
      return result;
    }
  };
}
const calc = createCalculator();
console.log(calc.add(1, 2)); // 3(计算并缓存)
console.log(calc.add(1, 2)); // 3(直接取缓存)
  1. 防抖/节流函数:依赖闭包保存定时器ID/触发时间。
javascript 复制代码
// 防抖函数(闭包实现)
function debounce(fn, delay) {
  let timer = null; // 闭包保存定时器ID
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}
// 节流函数(闭包实现)
function throttle(fn, interval) {
  let lastTime = 0; // 闭包保存上次执行时间
  return (...args) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
}
  1. 事件监听/回调:保留上下文变量。
javascript 复制代码
function bindEvent() {
  const btn = document.getElementById('btn');
  const msg = '点击成功'; // 闭包保留msg
  btn.addEventListener('click', () => {
    alert(msg);
  });
}
bindEvent();

注意事项

1.闭包会导致变量长期驻留内存,滥用可能导致内存泄漏(需手动释放,如将引用置为null)。

2.循环引用问题: 闭包与DOM元素互相引用可能导致内存泄漏。

3.数据元素遍历中,频繁创建闭包可能影响性能。

4.多层嵌套闭包导致作用域链查找变慢。

  1. 变量意外共享问题: 循环中创建闭包时的经典问题

相关推荐
萧曵 丶7 小时前
Vue 中父子组件之间最常用的业务交互场景
javascript·vue.js·交互
Amumu121388 小时前
Vue3扩展(二)
前端·javascript·vue.js
NEXT068 小时前
JavaScript进阶:深度剖析函数柯里化及其在面试中的底层逻辑
前端·javascript·面试
牛奶9 小时前
你不知道的 JS(上):原型与行为委托
前端·javascript·编译原理
牛奶10 小时前
你不知道的JS(上):this指向与对象基础
前端·javascript·编译原理
牛奶10 小时前
你不知道的JS(上):作用域与闭包
前端·javascript·电子书
pas13611 小时前
45-mini-vue 实现代码生成三种联合类型
前端·javascript·vue.js
颜酱12 小时前
数组双指针部分指南 (快慢·左右·倒序)
javascript·后端·算法
兆子龙12 小时前
我成了🤡, 因为不想看广告,花了40美元自己写了个鸡肋挂机脚本
android·javascript
SuperEugene12 小时前
枚举不理解?一文让你醍醐灌顶
前端·javascript