JavaScript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
一、闭包的本质定义
闭包是通过函数嵌套 函数来实现的。内部函数可以访问外部函数的变量,既是外部函数已经执行完毕。
function outer() {let secret = 123;return function inner() {console.log(secret); // 访问外部变量};}const fn = outer();fn(); // 123(仍能访问已销毁的outer作用域)
二、核心运行机制
-
作用域链保留:函数定义时捕获外层环境引用
-
生命周期延续:内部函数存在则外部变量不回收
-
动态访问:闭包变量可实时获取最新值
三,闭包的应用场景
1. 模块模式
const counter = (() => {let count = 0;return {add: () => ++count,get: () => count,reset: () => count = 0};})();counter.add();console.log(counter.get()); // 1
2. 私有变量封装
function Person(name) {let _age = 0;return {getName: () => name,setAge: age => _age = age,getInfo: () => `${name}(${_age})`};}const p = Person('Alice');p.setAge(25);console.log(p.getInfo()); // Alice(25)
3. 循环陷阱解决方案
for(var i=0; i<3; i++) {(function(j) {setTimeout(() => console.log(j), 100);})(i);}// 输出 0 1 2(不用闭包会输出3次3)
四,性能优化技巧
// 优化前:每次调用创建新闭包function heavy() {const data = new Array(1000000);return () => data.length;}// 优化后:复用闭包const light = (() => {const cache = new Map();return key => {if(!cache.has(key)) {cache.set(key, new Array(1000000));}return cache.get(key).length;}})();
箭头函数简化闭包:
const createAdder = x => y => x + y;const add5 = createAdder(5);console.log(add5(3)); // 8
五,注意
-
内存占用:
-
闭包可能会
-
导致一些内存占用问题,
-
特别是当他们引用大量数据时。
-
确保适当的管理这些引用
避免内存泄漏
-
垃圾回收:
-
现代JavaScript引擎(如V8)
-
会尝试优化闭包的内存管理,
-
但在编写代码时 仍需注意避免不必
-
要的闭包使用
-
性能:
-
在某些情况下,
-
频繁使用闭包可能会轻微影响性能,
-
尤其是在循环或频繁调用时。尽量避免不
-
必要的闭包可以提高性能
![]() |
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |




浙公网安备 33010602011771号