首页IT科技js闭包的使用([JavaScript]使用闭包实现点击按钮切换 toggle)

js闭包的使用([JavaScript]使用闭包实现点击按钮切换 toggle)

时间2025-09-18 09:16:09分类IT科技浏览6896
导读:前言 我以往在实现点击按钮切换DOM元素样式的时候,使用的是在全局范围内定义一个flag变量,然后用true和false来对应不同的状态。 const...

前言

我以往在实现点击按钮切换DOM元素样式的时候                ,使用的是在全局范围内定义一个flag变量                       ,然后用true和false来对应不同的状态                。 const btn = document.querySelector(#btn); //获取按钮元素 let flag = false; //flag是全局变量 //事件监听绑定点击事件 btn.addEventListener(click,function(){ if(flag){ //状态1 }else{ //状态2 } flag = !flag; //切换状态(通过修改flag的值:true或false) }); //...如果代码量很多的话        ,我们可能在其他地方不小心使用着同样叫做flag的变量 flag = doSomethingToFlag(); //其他代码可能对flag的值进行了(意料之外的)修改 这个flag变量其实本意上只是用在按钮的点击事件上            ,但是flag位于全局范围内                       ,其他代码都可以对flag的值进行修改           ,从而可能导致意料之外的情况发生                       。因此        ,使用全局变量表示不同状态是不可取的做法        。 最近在学习闭包的概念                        ,尝试着使用闭包实现点击按钮切换不同状态            。

分析

使用闭包我们可以把表示状态的flag变成私有变量                       。 const btn = document.querySelector(#btn); //获取按钮元素 function click(){ let flag = true; //这里的flag不再是全局变量 function closure(){ if(flag){ console.log(on); //这里表示状态1 }else{ console.log(off); //这里表示状态2 } flag = !flag; //切换状态 } return closure; } btn.addEventListener(click,click()); //绑定点击事件 console.log(flag); //报错:flag is not defined

我们在click()函数内部定义了closure()函数               ,当closure()函数被返回并在其他地方被使用后    ,它仍然引用着flag                        ,这就导致了click()函数被销毁                   ,但是flag不会被销毁,也就是形成了闭包           。

这里稍微对代码做一些改进                    ,使其复用性更高                       ,也就是封装toggle()函数: //toggle()函数接收一个按钮和两个函数:on()和off(); //其中on()表示第1种状态要执行的内容,off()表示第2种状态要执行的内容 function toggle(btn, on, off) { //使用闭包 function click() { let flag = true; function closure() { if (flag) { on();//这里执行状态1要执行的内容 } else { off();//这里执行状态2要执行的内容 } flag = !flag; } return closure; } //为按钮绑定点击事件 btn.addEventListener(click, click()); } 将功能封装好后    ,就可以很方便的将toggle事件绑定到按钮上: const btn = document.querySelectorAll(.btn); //获取若干个按钮 for (let i = 0; i < btn.length; i++) {//使用for循环为这些按钮都绑定toggle事件 //toggle函数的三个参数分别是:按钮DOM元素               、状态1要执行的内容                        、状态2要执行的内容 toggle(btn[i], function on() { //doSomething:这里填入状态1要执行的代码 }, function off() { //doSomething:这里填入状态2要执行的代码 }); } 经过测试可以发现                ,各个按钮对应的flag是独立的                       ,互不干扰的        。这是因为: 每一次绑定点击事件时        ,toggle()函数内部的click()函数占有一定内存空间            ,而函数调用后                       ,内存被回收           ,flag由于闭包的特性被保留下来; 又因为每次调用click()函数开辟的是不同的内存空间        ,因此内部对应的flag也是不同的                        ,故每一个按钮都能和一个flag一一对应               ,不会互相干扰                        。

参考文章

[1] JavaScript闭包 | 菜鸟教程

[2] 闭包 - JavaScript | MDN

[3] JavaScript高级程序设计(第4版) [美] 马特·弗里斯比(Matt Frisbie)——10.14 闭包

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
高德导航无法定位当前位置(高德地图定位获取不到报错INVALID_USER_SCODE) 文章生成器app下载(智能AI文章生成器——提高内容创作效率的新工具!)