
关于JS中闭包剖析(包含闭包的理解、作用、生命周期、应用、缺点及其解决、常见的闭包)
函数嵌套。 内部函数引用了外部函数的数据或函数。 外部函数被调用。 延长局部变量生命周期:避免局部变量的销毁,保证外部函数能够访问内部变量。 封装访问权限:确保内部函数只能通过指定方式访问外部数据,防止外部随意修改。 预解析阶段:验证函数嵌套,确定闭包变量。 闭包释放条件:闭包所在的变量被清理,或者手动释放。 隐式创建闭包:
发布日期:2021-05-12 21:17:48
浏览次数:21
分类:精选文章
本文共 3002 字,大约阅读时间需要 10 分钟。
JS中的闭包理解剖析
JS中的闭包抽象了函数与其周围环境之间的关系,避免了显式的环境传递,是函数嵌套编程的核心能力。以下从基础到应用,全面剖析JS中的闭包。
闭包的产生条件
闭包产生的前提条件是:
例如:
function fn1() { const a = 1; function fn2() { console.log(a); }; return fn2;}function fn3() { const b = 2; fn2();}const f = fn1();f(); // 输出:1f(); // 输出:1
闭包使得变量 a
存续存在,避免了局部变量的常规释放过程。
常见闭包形式
1. 函数返回一个函数
function fnReturningClosure() { let count = 0; function fn() { count++; return count; }; return fn;}const add = fnReturningClosure();add(); // 输出:1add(); // 输出:2
返回新函数,形成闭包,其内部直接访问外部 count
。
2. 传递函数作为参数
function transmissionClosing() { function innerFn() { console.log('Inner'); }; return innerFn;}transmissionClosing()();
当函数作为参数传递,内部函数在传递过程中形成闭包,确保能访问传递者的上下文。
闭包的作用
代码分析
function fn1() { const a = 1; function fn2() { console.log(a); }; return fn2;}function fn3() { const b = 2; fn2();}const f = fn1();f(); // a 存在f = null; // 闭包释放f(); //无法调用,a 已经释放
闭包生命周期
闭包在预解析阶段创建,保持脚本执行期间存在。若不引用闭包,会在函数调用后自动释放。
关键点
示例
function createClosure() { const x = 'Closure Created!'; function inner() { console.log(x); }; return inner;}createClosure();
- 显式创建闭包:
- 封装功能:
- 匿名函数实现:
避免不必要的闭包:抵消闭包的形成条件。
及时释放闭包:
function explicitClosure() { const y = 'Explicitly Created!'; function inner() { console.log(y); }; return inner;}const closure = explicitClosure();closure();
闭包应用
模块化编程
function myModule() { const msg = 'I Love SWPU'; function doSomething() { console.log('doSomething() ' + msg.toUpperCase()); } function doOtherthing() { console.log('doOtherthing() ' + msg.toLowerCase()); } return { doSomething: doSomething, doOtherthing: doOtherthing };}window.myModule = myModule();
(function() { const msg = 'I Love SWPU'; function doSomething() { console.log('doSomething() ' + msg.toUpperCase()); } function doOtherthing() { console.log('doOtherthing() ' + msg.toLowerCase()); } window.myModule2 = { doSomething: doSomething, doOtherthing: doOtherthing };})();
优化技巧
将闭包添加为 window
属性,避免每次加载重新创建,便于多次使用。
(if (typeof window !== 'undefined') {(function(window) { const msg = 'I Love SWPU'; function doSomething() { console.log('doSomething() ' + msg.toUpperCase()); } function doOtherthing() { console.log('doOtherthing() ' + msg.toLowerCase()); } window.myModule2 = { doSomething: doSomething, doOtherthing: doOtherthing };})(window);})
闭包的缺点及解决
问题
闭包导致内存泄漏,缺点在于长时间运行内存占用过高。
解决方法
function fn() { const arr = []; for (let i = 0; i < 10; i++) { arr.push({ key: i, value: 'Closure Test' }); } function inner() { console.log(arr); }; inner(); // 处理完后释放 inner = null;}fn();
总结:闭包在JS中扮演着至关重要的角色,理解其特性和使用方法,是提升代码质量和效率的关键。
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月22日 14时49分32秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
ssm(Spring+Spring mvc+mybatis)——saveDept.jsp
2019-03-11
JavaScript操作BOM对象
2019-03-11
layui二级联动
2019-03-11
SpringCloud分布式服务-我的理解
2019-03-11
解决Chrome播放视频闪屏黑屏无法播放
2019-03-11
Java中final的理解
2019-03-11
Git简单理解与使用
2019-03-11
echarts 基本图表开发小结
2019-03-11
二分查找.基于有序数组的查找方法.704
2019-03-11
C语言文档操作
2019-03-11
制作JS验证码(简易)
2019-03-11
adb通过USB或wifi连接手机
2019-03-11
vue使用ecahrts词云图
2019-03-11
【README】回溯算法基本框架
2019-03-11
数组中常见的算法
2019-03-11
泛型机制 Generic
2019-03-11
包装类
2019-03-11
JDK9-15新特性
2019-03-11