JavaScript闭包实战:利用闭包实现按钮状态切换与变量持久化

作者:函数茶馆

时间:2026-10-22

浏览:253

本文深入解析JavaScript闭包在按钮状态切换中的应用。通过立即执行函数(IIFE)创建闭包,使内部变量在函数执行后仍保留在内存中,避免使用全局变量带来的维护问题。文章对比了闭包方案与全局变量方案的代码实现,并详细阐述了闭包读取内部变量及保持变量值的核心用途,帮助开发者理解闭包的内存管理机制。

文章目录

基于闭包的按钮状态切换实现

利用JavaScript闭包特性实现按钮状态的切换功能。

具体实现代码如下所示:


var toggleBtn = document.getElementById('toggle');
var toggleFun = (function() {
 var checked = true;
 return function() {
  var color = checked ? 'red' : 'white';
  toggleBtn.style.backgroundColor = color;
  checked = !checked;
 };
})();
// 切换按钮
toggleBtn.addEventListener('click', toggleFun);

代码逻辑解析如下:

上述代码实现了点击按钮切换背景样式的功能,其核心原理依赖于JavaScript的闭包机制。简要说明如下:

变量toggleFun是一个立即执行函数(IIFE)的执行结果,执行完毕后,toggleFun被赋值为该函数返回的内部函数:


 toggleFun = function() {
   color = checked ? 'red' : 'white';
   toggleBtn.style.backgroundColor = color;
   checked = !checked;
 }

该内部函数引用了外部函数的checked变量,这正是checked变量在立即执行函数执行结束后未被销毁的原因,因为仍有其他部分代码在使用它。此内部函数作为事件监听器的回调函数,每次点击按钮时都会被调用一次,通过修改checked的值来实现按钮样式的切换。由于立即执行函数内的内部函数被全局作用域下的toggleFun变量所引用,从而形成了一个闭包。

简而言之,闭包的作用在于:当立即执行函数执行完毕并返回后,JavaScript的垃圾回收机制不会回收立即执行函数所占用的资源,这是因为立即执行函数的内部函数依赖于其外部函数的变量。

上述解释较为繁琐,下面对代码进行简化并添加注释,以便更清晰地展示逻辑:


var toggleBtn = document.getElementById('toggle');
var outerFun = function() {
 var checked = true;
 // innerFun声明时用到了outerFun的局部变量
 var innerFun = function() {
  var color = checked ? 'red' : 'white';
  toggleBtn.style.backgroundColor = color;
  checked = !checked;
 };
 return innerFun;
};
var toggleFun = outerFun(); // toggleFun指向innerFun
// 切换按钮,每次点击都会调用innerFun
toggleBtn.addEventListener('click', toggleFun);

全局变量方案与闭包的对比

不使用闭包,改用全局变量的实现方式。

实际上,即使不使用闭包也能实现按钮切换功能,但需要借助全局变量来存储按钮的状态:


var toggleBtn = document.getElementById('toggle');
var checked = true; // 全局变量存储按钮状态
var toggleFun = function() {
 var color = checked ? 'red' : 'white';
 toggleBtn.style.backgroundColor = color;
 checked = !checked;
};
toggleBtn.addEventListener('click', toggleFun);

然而,过度使用全局变量会导致代码难以维护,且状态控制变得复杂。

JavaScript闭包概念与用途解析

补充内容:JavaScript闭包的概念及具体用法。

1. 闭包的基本概念:

闭包是指能够读取其他函数内部变量的函数。

例如以下代码结构:


function f1(){
    var n=999;
    function f2(){
      alert(n); 
    }
    return f2;
  }
  var result=f1();
  result(); // 999

其中f2函数即为闭包。

在JavaScript语言中,只有函数内部的子函数才能读取局部变量,

因此可以将闭包简单理解为“定义在一个函数内部的函数”。

从本质上看,闭包是将函数内部与函数外部连接起来的一座桥梁。

2. 闭包的主要用途:

闭包的应用场景广泛,其最大用途有两个:一是如前所述,可以读取函数内部的变量;

二是让这些变量的值始终保持在内存中。

如何理解这一结论?请参考以下代码示例。


  function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次输出的值是999,

第二次输出的值是1000。这证明了函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

造成这种现象的原因在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终存在于内存中,

而f2的存在依赖于f1,因此f1也始终保留在内存中,不会在调用结束后被垃圾回收机制(garbage collection)回收。

这段代码中另一个值得注意的细节是nAdd=function(){n+=1}"这一行代码,

首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。

其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,

所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

总结

以上介绍了JavaScript闭包在按钮切换功能中的应用,希望以上内容对您有所帮助。如有任何疑问,欢迎留言,小编会及时回复。感谢大家对本站的支持!

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章