JavaScript 闭包原理与单例模式实战

作者:代码拾荒

时间:2026-10-21

浏览:313

本文深入解析JavaScript闭包的核心机制,通过计数器示例展示内部变量如何被外部函数引用并持久化。进一步探讨闭包在前端开发中的典型应用场景,利用闭包特性实现单例模式,解决如遮罩层等全局资源唯一实例的管理问题,帮助开发者理解闭包在状态保持与资源控制中的实际价值。

文章目录

JavaScript 闭包原理与单例模式实战

JavaScript 闭包详解及实例:

近期在梳理 JavaScript 基础概念时,重点研究了闭包。起初对此存在诸多疑问,经过持续查阅资料与深入思考,对闭包的理解逐渐清晰。以下将结合具体案例阐述个人对闭包机制的见解。


 function fn(){
  var a = 0;
  return function (){
    return ++a;
  }  
 }

闭包机制解析

如前文代码所示,第一个 return 语句返回的即为一个闭包。从本质上看,闭包本质上就是一个函数。那么,返回这个函数的实际意义何在?

关键在于该函数能够访问其外部作用域中的变量 a。换言之,return 返回的不仅仅是函数本身,还包含了对外部变量 a 的引用。

接下来,我们利用这个闭包进行进一步的操作演示。

我们可以定义一个变量 var f = fn(); 若执行 console.log(f),会发现 f 存储的是 return 返回的整个函数体,即 function () { return ++a; }。

执行 f() 等同于执行该函数。此时,若多次调用 f(),返回的 a 值会持续累加,体现了闭包对变量状态的保持能力。

然而,若此时再定义变量 var f2 = fn(); 并调用 f2(),可观察到 a 的值被重置。此时计数将重新从 0 开始。此现象的原因何在?

可以这样理解:闭包本身是一个匿名函数,当将其赋值给变量时,它便拥有了标识符。每次执行后,函数及其引用的变量会存储在独立的内存空间中。由于每个变量指向的内存空间互不干扰,它们成为独立的个体,因此 a 的值在不同变量间互不影响。这相当于执行了不同的函数,尽管函数体代码相同。

闭包在单例模式中的应用

那么,闭包有哪些实际应用场景?此前因经验不足,代码中较少直接使用闭包。但在阅读前端设计模式时,发现单例模式是闭包的一个极佳应用场景。

假设需求如下:网页中可能需要遮罩层,调用时若已存在则复用,不存在则创建。但考虑到可能永远不需要遮罩层,因此不应在页面加载时立即创建,而应延迟初始化。

这是一个非常典型的单例模式应用场景。

那么如何实现这一逻辑?


 function fn() {
  var a;
  return function() {
     return a || (a = document.body.appendChild(document.createElement('div')));
  }
 };
 var f = fn();
f();

实现方式很简单,只需对之前的代码稍作调整。相关原理已在上述内容中详细阐述,仔细研读即可理解。

至此,对闭包有了更深入的理解。后续将继续深入探索,并及时更新相关内容。

感谢阅读,希望本文能对大家有所帮助,感谢支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章