公司动态

闭包(Closure)概念与案例

📅 2026/8/14 18:44:55
闭包(Closure)概念与案例
**闭包Closure**是函数式编程和许多现代语言尤其是 JavaScript、Python、Swift、Kotlin 等中的核心概念。1. 概念是什么闭包是一个函数加上它被创建时所能访问的**词法作用域lexical scope**中的变量的引用。简单说一个内部函数可以访问外部函数的变量。即使外部函数已经执行完毕、返回了内部函数依然能“记住”并使用那些外部变量。这些被“记住”的变量和内部函数一起构成了闭包。关键特征词法作用域变量的作用域在代码书写时就确定了而不是运行时。持久化外部函数的局部变量不会因为函数执行结束而被销毁只要还有闭包引用它。2. 作用是什么闭包的主要作用可以概括为作用说明数据私有化 / 封装让变量不被外部直接访问只能通过特定接口操作状态保持函数可以“记住”上一次的状态实现有状态的函数延迟执行 / 回调把函数和它的环境一起传递稍后再执行时仍能访问原来的变量工厂函数 / 函数工厂通过参数生成具有不同行为的函数模块化在没有 class 的早期语言中模拟私有变量和模块3. 能解决什么实际问题实现私有变量真正的封装在 JavaScript 中没有真正的 private 关键字ES2022 之前闭包是实现私有数据的经典方式。函数记忆上一次的计算结果 / 状态比如计数器、节流、防抖、缓存等。解决循环中的异步问题经典坑在for循环里创建多个异步回调时闭包可以正确捕获每次循环的值。高阶函数与柯里化把多参数函数变成一系列单参数函数或者实现部分应用partial application。事件处理与回调点击按钮时需要访问创建时的上下文变量。模块模式Module Pattern在早期 JS 中实现命名空间和私有成员。4. 典型案例案例 1计数器最经典functioncreateCounter(){letcount0;// 私有变量returnfunction(){// 闭包count;returncount;};}constcounter1createCounter();constcounter2createCounter();console.log(counter1());// 1console.log(counter1());// 2console.log(counter2());// 1 各自独立案例 2函数工厂根据参数生成不同行为functionmakeMultiplier(factor){returnfunction(x){returnx*factor;};}constdoublemakeMultiplier(2);consttriplemakeMultiplier(3);console.log(double(5));// 10console.log(triple(5));// 15案例 3解决循环 异步的经典问题// 错误写法所有都输出 3for(vari0;i3;i){setTimeout(()console.log(i),100);}// 用闭包修复for(vari0;i3;i){(function(j){// 立即执行函数创建闭包setTimeout(()console.log(j),100);})(i);}// 现代写法let 本身就有块级作用域for(leti0;i3;i){setTimeout(()console.log(i),100);}案例 4防抖Debouncefunctiondebounce(fn,delay){lettimernull;returnfunction(...args){clearTimeout(timer);timersetTimeout((){fn.apply(this,args);},delay);};}consthandleSearchdebounce((keyword){console.log(搜索:,keyword);},300);案例 5模块模式IIFE 闭包constCalculator(function(){letresult0;// 私有return{add(x){resultx;returnthis;},subtract(x){result-x;returnthis;},getResult(){returnresult;}};})();Calculator.add(10).subtract(3);console.log(Calculator.getResult());// 7总结闭包 函数 它诞生时的环境。它让函数拥有“记忆力”能够封装数据、保持状态、延迟执行是 JavaScript 等语言实现高级抽象的重要基础。理解闭包也就理解了作用域、生命周期和函数式编程的核心思想。