【前端学习】背闭包快疯了?我用实际场景搞懂了!

🔥 为啥写这个?

最近疯狂背八股,闭包概念懂了,但一到实际开发就懵... 昨天写组件终于悟了!分享给同被折磨的友友~

一、闭包是啥?

简单说就是:函数嵌套时,内层函数能记住外层函数的变量,哪怕外层执行完了。

举个🌰:写一个延迟计数器(点击按钮,1 秒后数字 +1 ),用闭包实现:

js 复制代码
function createCounter() {
    let count = 0; 
    return () => { 
        setTimeout(() => { 
            count++; // 内层函数"记住"count,每次调用持续累加 console.log(count);
        }, 1000);
    };
} 
    
    const add = createCounter(); 
    add(); // 1秒后输出 1 
    add(); // 1秒后输出 2(闭包保留了 count=1 的状态)

二、实际开发踩坑:数据更新不生效

场景:延迟更新页面数据

假设做一个按钮,点击后 1 秒更新页面显示的数字,直接用闭包会遇到 "数据改了,但页面没变化" 的问题:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>闭包踩坑示例</title>
</head>
<body>
  <button id="btn">延迟+1</button>
  <div id="result">count: 0</div>

  <script>
    let count = 0; 
    const btn = document.getElementById('btn');
    const result = document.getElementById('result');

    btn.addEventListener('click', () => {
      setTimeout(() => {
        count++; 
        result.innerText = `count: ${count}`; // 手动更新 DOM!
      }, 1000);
    });
  </script>
</body>
</html>

为啥坑?

  • 纯 JS 开发时,普通变量修改后不会自动更新 DOM ,必须手动操作 innerText/innerHTML。
  • 如果用框架(如 Vue/React),不配合响应式语法,也会遇到类似问题!

三、正确姿势:结合开发场景适配

方案 1:手动更新 DOM(纯 JS 开发)

html 复制代码
<script>
  let count = 0; 
  const btn = document.getElementById('btn');
  const result = document.getElementById('result');

  btn.addEventListener('click', () => {
    setTimeout(() => {
      count++; 
      // 关键:手动更新 DOM,让页面变化
      result.innerText = `count: ${count}`; 
    }, 1000);
  });
</script>

核心逻辑 :JS 不自动监听变量变化,修改数据后必须手动操作 DOM 才能更新页面。

方案 2:配合框架响应式(以 React 为例)

React 中,用 useState 管理状态,闭包捕获 setState 来更新:

jsx 复制代码
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); 

  const handleClick = () => {
    setTimeout(() => {
      // 用 setCount 触发响应式更新
      setCount(prev => prev + 1); 
    }, 1000);
  };

  return (
    <div>
      <button onClick={handleClick}>延迟+1</button>
      <div>count: {count}</div> 
    </div>
  );
}

避坑点:

  • 直接修改 count(如 count++ )不会触发更新,必须用 setState。
  • 闭包若捕获旧的 count 值,会导致 "状态不更新"(俗称 stale closure 问题),用函数式更新(prev => prev + 1 )可解决。

四、闭包必用场景(开发高频需求)

场景 1:搜索框防抖(避免频繁请求)

js 复制代码
// 用闭包保存定时器 ID,防止重复触发
const debounce = (fn, delay) => {
  let timer = null; // 闭包变量,多次调用不会重置
  return function() {
    if (timer) clearTimeout(timer); 
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
};

// 实际用:监听输入框变化
const input = document.getElementById('search-input');
input.addEventListener('input', debounce((e) => {
  console.log('发请求搜索:', e.target.value);
}, 500));

踩坑点:如果不用闭包,每次输入都会重置定时器,防抖功能直接失效!

场景 2:模块私有变量(避免全局污染)

js 复制代码
//  utils/counter.js
const createCounter = () => {
  let count = 0; // 闭包变量,外部无法访问
  return {
    increment: () => count++,
    getCount: () => count
  };
};

// 其他文件引入
import { createCounter } from './utils/counter.js';

const counter = createCounter();
counter.increment();
console.log(counter.getCount()); // 输出 1(外部无法直接改 count)

价值:做工具库 / 组件时,用闭包实现 "私有状态",防止全局变量污染。

五、避坑总结:闭包开发关键提醒

开发场景 正确姿势 常见错误
纯 JS 开发 修改数据后手动更新 DOM 只改变量,页面不变化
React 开发 用 useState/ 函数式更新 直接修改状态,不触发更新
工具库开发 用闭包封装私有变量 全局变量污染逻辑

六、总结:闭包该咋用?

✅ 场景:需要 "记住" 变量状态时(比如防抖函数、组件私有变量)

❌ 踩坑:和 React 响应式结合时,注意用useState包裹

💡 小技巧:写闭包后,检查变量是 "值传递" 还是 "引用传递"

最后碎碎念

背八股真的好痛苦... 但把知识点砸到项目里,突然就通了! 你们遇到过这些坑吗?

  • 用闭包写防抖,第一次点击没生效?(定时器逻辑没处理好!)
  • React 里遇到 "陈旧闭包",状态永远是旧的?
  • 有没有不用闭包也能实现类似功能的奇技淫巧?
相关推荐
云浪3 小时前
Go 并发实战:从零实现一个高并发安全的任务调度器
javascript·后端·go
OpsEye11 小时前
大模型账单对账难:不同厂商 Token 统计口径差异怎么处理
javascript·ai编程
全栈项目管理程序猿11 小时前
ArcGIS JS 基础教程(32):体元系列 - VoxelSlice 体元切片
前端·javascript
Hilaku13 小时前
AI 流式输出都用 SSE,什么时候必须换 WebSocket?
前端·javascript·程序员
奇牙coding13 小时前
Codex CLI 升级后多文件编辑静默失效:config.yaml 枚举变更排查与修复指南
java·前端·javascript·ai
不简说14 小时前
AI 帮你画模板、点一下就云打印:sv-print 这三个月都干了啥
前端·javascript·人工智能
大明二代15 小时前
从零构建 Mastra RAG MVP:DeepSeek、SiliconFlow 与 PostgreSQL/pgvector 实战
javascript·数据库·人工智能
结局无敌15 小时前
React Native for OpenHarmony 实战:三方库 react-native-paper 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·ecmascript·harmonyos
铁皮饭盒15 小时前
CPU就行, 老照片变清晰, 本地部署582mb腾讯的模型, 本地部署, 过节了给长辈们变个小魔术
前端·javascript·后端
结局无敌15 小时前
React Native for OpenHarmony 实战:三方库 react-native-progress-steps 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·harmonyos