什么是闭包

什么是闭包

闭包定义

在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. 变量意外共享问题: 循环中创建闭包时的经典问题

相关推荐
编程牛马姐1 小时前
独立站SEO流量增长:提高Google排名的优化方法
前端·javascript·网络
妮妮喔妮5 小时前
supabase的webhook报错
开发语言·前端·javascript
qq_12084093715 小时前
Three.js 大场景分块加载实战:从全量渲染到可视集调度
开发语言·javascript·数码相机
漂流瓶jz6 小时前
运行时vs编译时:CSS in JS四种主流方案介绍和对比
前端·javascript·css
钮钴禄·爱因斯晨7 小时前
他到底喜欢我吗?赛博塔罗Java+前端实现,一键解答!
java·开发语言·前端·javascript·css·html
Watermelo6177 小时前
理解 JavaScript 中的“ / ”:路径、资源与目录、nginx配置、请求、转义的那些事
前端·javascript·vue.js·chrome·nginx·正则表达式·seo
Hello--_--World8 小时前
JS:this指向、bind、call、apply、知识点与相关面试题
开发语言·javascript·ecmascript
jserTang8 小时前
手撕 Claude Code-4: TodoWrite 与任务系统
前端·javascript·后端
腹黑天蝎座8 小时前
大屏开发必读:Scale/VW/Rem/流式/断点/混合方案全解析(附完整demo)
前端·javascript
jserTang8 小时前
手撕 Claude Code-5:Subagent 与 Agent Teams
前端·javascript·后端