javascript闭包的使用之按钮切换功能


Posted in Javascript onAugust 30, 2018

闭包实现按钮状态切换

看下面的代码:

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);

解释

上面的代码实现了点击按钮切换样式的功能,它用到了js的闭包特性。简单解释下:

toggleFun为一个立即执行函数,执行后toggleFun被赋值为内部函数:

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

这个函数用到了外部函数的checked变量,这也是checked变量在立即执行函数执行完成后未被销毁的原因,因为还有其他地方用到了它。那么这个内部函数被用作事件监听器的回调函数,每点击一次就会被调用一次,从而可以通过更改checked的值来实现按钮切换效果。立即执行函数内的函数被全局下的toggleFun变量引用了,这就创建了一个闭包。

简而言之,闭包的作用就是在立即执行函数执行完并返回后,使得javascript的垃圾回收机制不会收回立即函数所占用的资源,因为立即执行函数的内部函数依赖立即执行函数中的变量。

额,上面写的太??铝耍?旅姘汛?肷晕⒏南拢?有┳⑹途突岣?忧逦??/p>

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闭包的概念及用法

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闭包的使用之按钮切换功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
基于jquery的表格排序
Sep 11 Javascript
javascript的创建多行字符串的7种方法
Apr 29 Javascript
关于jQuery判断元素是否存在的问题示例探讨
Jul 21 Javascript
关于Javascript加载执行优化的研究报告
Dec 16 Javascript
深入浅析JavaScript中的arguments对象(强力推荐)
Jun 03 Javascript
详解微信小程序——自定义圆形进度条
Dec 29 Javascript
JS实现仿百度文库评分功能
Jan 12 Javascript
详解vue2父组件传递props异步数据到子组件的问题
Jun 29 Javascript
React Native 使用Fetch发送网络请求的示例代码
Dec 02 Javascript
vue嵌套路由与404重定向实现方法分析
May 04 Javascript
angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例
Aug 17 Javascript
Vue 实现列表动态添加和删除的两种方法小结
Sep 07 Javascript
Vue.set() this.$set()引发的视图更新思考及注意事项
Aug 30 #Javascript
基于Angularjs-router动态改变Title值的问题
Aug 30 #Javascript
从vue源码解析Vue.set()和this.$set()
Aug 30 #Javascript
vue-router动态设置页面title的实例讲解
Aug 30 #Javascript
解决vue select当前value没有更新到vue对象属性的问题
Aug 30 #Javascript
微信小程序使用wxParse解析html的实现示例
Aug 30 #Javascript
vue中rem的配置的方法示例
Aug 30 #Javascript
You might like
PHP使用Mysql事务实例解析
2014/09/08 PHP
浅析PHP中json_encode与json_decode的区别
2020/07/15 PHP
基于jquery的多功能软键盘插件
2012/07/25 Javascript
无缝滚动js代码通俗易懂(自写)
2013/06/19 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
JS运动相关知识点小结(附弹性运动示例)
2016/01/08 Javascript
原生js实现倒计时--2018
2017/02/21 Javascript
js实现网页的两个input标签内的数值加减(示例代码)
2017/08/15 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
Vue中 v-if/v-show/插值表达式导致闪现的原因及解决办法
2018/10/12 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
vue 重塑数组之修改数组指定index的值操作
2020/08/09 Javascript
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
跟老齐学Python之数据类型总结
2014/09/24 Python
Python随机数random模块使用指南
2016/09/09 Python
教你用Python写安卓游戏外挂
2018/01/11 Python
python模拟表单提交登录图书馆
2018/04/27 Python
python 给DataFrame增加index行名和columns列名的实现方法
2018/06/08 Python
详解python中@的用法
2019/03/27 Python
PyQt5实现QLineEdit添加clicked信号的方法
2019/06/25 Python
Python 根据日志级别打印不同颜色的日志的方法示例
2019/08/08 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
Python shutil模块用法实例分析
2019/10/02 Python
torch 中各种图像格式转换的实现方法
2019/12/26 Python
python BeautifulSoup库的安装与使用
2020/12/17 Python
python 30行代码实现蚂蚁森林自动偷能量
2021/02/08 Python
小程序canvas中文字设置居中锚点
2019/04/16 HTML / CSS
Diptyque英国官方网站:源自法国的知名香氛品牌
2019/08/28 全球购物
Linux的主要特性
2014/10/06 面试题
2014年党员学习“三严三实”思想汇报
2014/09/15 职场文书
认错检讨书
2014/10/02 职场文书
合伙开公司协议书范本
2014/10/28 职场文书
健康状况证明书
2014/11/26 职场文书
戒赌保证书
2015/05/11 职场文书
pd.DataFrame中的几种索引变换的实现
2022/06/16 Python