说说闭包的理解和应用场景?

这个问题是 JS 面试高频题 👍

而且如果你有 7 年前端经验,面试官会期待你说到:

  • 原理
  • 作用域链
  • 内存机制
  • 实际应用场景
  • 优缺点

我给你一套「中高级面试回答版本」。


一、什么是闭包?

一句话定义:

闭包是函数和其词法作用域的组合。

通俗一点:

复制代码
函数可以记住并访问它定义时的作用域
即使函数在作用域外执行

二、核心本质(一定要讲)

闭包产生的本质原因:

复制代码
函数执行后,其内部变量没有被销毁
因为有外部引用在使用它

本质是:

复制代码
函数 + 作用域链 + 垃圾回收机制

三、最经典例子

scss 复制代码
function outer() {
  let count = 0;

  return function inner() {
    count++;
    console.log(count);
  }
}

const fn = outer();

fn(); // 1
fn(); // 2

为什么 count 没被销毁?

因为:

sql 复制代码
inner 函数引用了 outer 的变量
outer 的执行上下文不能被回收

这就是闭包。


四、从作用域链角度解释(进阶说法)

JS 在创建函数时,会保存:

lua 复制代码
[[Environment]]

也就是函数定义时所在的词法环境。

即使 outer 执行结束:

sql 复制代码
inner 依然持有 outer 的作用域引用

五、闭包的应用场景(面试重点 ⭐⭐⭐)


1️⃣ 数据私有化(最经典)

javascript 复制代码
function createCounter() {
  let count = 0;

  return {
    add() { count++ },
    get() { return count }
  }
}

const counter = createCounter();

实现:

复制代码
私有变量

这在早期 JS 中是实现"类私有属性"的方式。


2️⃣ 防抖 / 节流

javascript 复制代码
function debounce(fn, delay) {
  let timer = null;

  return function() {
    clearTimeout(timer);
    timer = setTimeout(fn, delay);
  }
}

timer 被闭包保存。


3️⃣ 循环绑定事件(经典面试题)

css 复制代码
for (var i = 0; i < 3; i++) {
  (function(i){
    setTimeout(() => {
      console.log(i);
    }, 1000)
  })(i)
}

利用闭包保存每次的 i。

(当然现在可以用 let)


4️⃣ 模块化(早期 IIFE)

javascript 复制代码
const module = (function(){
  let privateVar = 1;

  return {
    get() {
      return privateVar;
    }
  }
})();

5️⃣ React Hooks 本质

比如:

scss 复制代码
useState()

内部就是通过闭包保存状态。


六、闭包的优缺点

优点

  • 数据私有
  • 延长变量生命周期
  • 实现函数式编程

缺点

  • 容易造成内存泄漏
  • 滥用会增加内存占用

七、什么时候会导致内存泄漏?

如果闭包引用了:

复制代码
DOM 节点
大对象
长期不释放

就会导致 GC 无法回收。

比如:

javascript 复制代码
function fn() {
  const dom = document.getElementById('box');

  return function() {
    console.log(dom);
  }
}

只要返回函数没释放,dom 就不会被回收。


八、面试标准回答模板(你可以直接背)

闭包是函数和其词法作用域的组合。

当内部函数引用外部函数变量时,外部函数执行完后变量不会被销毁,从而形成闭包。

本质是作用域链和垃圾回收机制的结果。

常见应用包括数据私有化、防抖节流、模块化封装、事件绑定等。

相关推荐
Canace1 小时前
Harness Engineering 到底在做什么
前端·人工智能·ai编程
用户84298142418101 小时前
JS代码压缩实测:可减小体积、提高执行效率!
前端·javascript·后端
snow@li1 小时前
Vue Axios封装与SpringBoot Payload封装全景关联分析(前后端数据交互底层闭环)
前端·vue.js·spring boot
Csvn1 小时前
🐛 React StrictMode 下 useEffect 执行两次:不是 Bug,是特性
前端
做好一个小前端1 小时前
ECharts 折线图大数据量性能优化参考
前端·性能优化·echarts
渣波1 小时前
🧭 从 URL 到组件:深度剖析 React Router 原理与 SPA 路由架构艺术
前端
用户852495071841 小时前
一个 useRef,三种人生:从 DOM 引用到 Web Worker
前端
无人生还1 小时前
从 Vue3 到 React · 快速上手系列第 13 篇:工程化与综合实战(Vite + Todo 应用)
前端·vue.js·react.js
晴殇i2 小时前
用 TRAE Work 搞定客户项目介绍,开发再也不用头疼写汇报 PPT
前端·后端
Cache技术分享2 小时前
488. Java 反射 - 动态创建数组
前端·后端