深入浅出理解JavaScript闭包的功能与用法


Posted in Javascript onAugust 01, 2018

本文实例讲述了JavaScript闭包的功能与用法。分享给大家供大家参考,具体如下:

理解闭包关键是理解JS的对象的本质以及垃圾收集机制。函数也是对象,也有属性,通常执行一个函数时,局部变量在函数执行完后,内存会被回收,这是JS的垃圾收集机制决定的,如果想保存局部变量所占用的内存,就必须把保存在另一个不被回收的变量中,通常是全局变量。函数在创建时,内部属性[[Scope]]保存了作用域链,作用域链中包含外部函数以及全局对象的变量,被称为变量对象。所以把内部函数返回时,由于把函数保存了,所以内部属性[[Scope]]所保存的变量对象也就保存了而没有被回收,因此局部变量也就被保存了。

最简单的闭包:

function f1() {
 var i = 0;
 return function () {
 var j = 0;
 i++;
 console.log(i,j);
 };
}
var fn = f1();
fn();//1 0
fn();//2 0

还有诸如给元素添加事件,事件函数保存着外部函数的变量,通过这个特性可以让按钮显示被点击次数。

当然可以创建多层闭包,最内部函数保存所有外部函数以及全局对象的变量,但并不是任何地方都用闭包,因为其始终都带有[[Scope]]属性,所有比较占内存,所以在需要的时候才用。

闭包在模块化编程,为函数或对象创建私有变量的时候非常有用,可以避免全局污染以及变量命名冲突的问题。

值得注意的是因为[[Scope]]与函数有关,如上述例子,在两次执行f1函数把返回的函数保存在不同的变量中,其外部函数的变量是互不影响的。如:

function f1() {
 var i = 0;
 return function () {
 var j = 0;
 i++;
 console.log(i,j);
 };
}
var fn = f1();
fn();//1 0
fn();//2 0
var fn1 = f1();
fn1();//1 0
fn(); //3 0
fn1();//2 0

感兴趣的朋友可以使用在线HTML/CSS/JavaScript前端代码调试运行工具:http://tools.3water.com/code/WebCodeRun测试一下上述代码的运行效果,以加深对javascript闭包的认识。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript常用函数技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript权威指南 学习笔记之null和undefined
Sep 25 Javascript
Javascript和Java获取各种form表单信息的简单实例
Feb 14 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
May 28 Javascript
js实现ArrayList功能附实例代码
Oct 29 Javascript
node.js中的console.info方法使用说明
Dec 09 Javascript
在Google 地图上实现做的标记相连接
Jan 05 Javascript
AngularJS实现数据列表的增加、删除和上移下移等功能实例
Sep 05 Javascript
JS查找字符串中出现最多的字符及个数统计
Feb 04 Javascript
Vue内容分发slot(全面解析)
Aug 19 Javascript
微信小程序使用modal组件弹出对话框功能示例
Nov 29 Javascript
JS二级菜单不同实现方法分析【4种方法】
Dec 21 Javascript
javascript实现获取中文汉字拼音首字母
May 19 Javascript
Angular路由ui-router配置详解
Aug 01 #Javascript
javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】
Aug 01 #Javascript
JavaScript事件冒泡与事件捕获实例分析
Aug 01 #Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
Aug 01 #Javascript
create-react-app 修改为多入口编译的方法
Aug 01 #Javascript
Vue项目全局配置页面缓存之按需读取缓存的实现详解
Aug 01 #Javascript
JavaScript执行环境及作用域链实例分析
Aug 01 #Javascript
You might like
php中curl、fsocket、file_get_content三个函数的使用比较
2014/05/09 PHP
mysql_connect localhost和127.0.0.1的区别(网络层阐述)
2015/03/26 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
2016/12/29 PHP
php实现页面纯静态的实例代码
2017/06/21 PHP
Javascript 继承机制的实现
2009/08/12 Javascript
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
jQuery 页面 Mask实现代码
2010/01/09 Javascript
document.createElement()用法及注意事项(ff下不兼容)
2013/03/13 Javascript
Jquery EasyUI的添加,修改,删除,查询等基本操作介绍
2013/10/11 Javascript
js判断iframe内的网页是否滚动到底部触发事件
2014/03/18 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
2014/05/23 Javascript
JS实现的页面自定义滚动条效果
2015/10/26 Javascript
JS弹出窗口的运用与技巧大全
2016/11/01 Javascript
jQuery实现滚动条滚动到子元素位置(方便定位)
2017/01/08 Javascript
Angular中封装fancyBox(图片预览)遇到问题小结
2017/09/01 Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
2018/10/28 Javascript
详解es6新增数组方法简便了哪些操作
2019/05/09 Javascript
vue input标签通用指令校验的实现
2019/11/05 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
vue项目接口域名动态获取操作
2020/08/13 Javascript
微信小程序实现左滑删除效果
2020/11/18 Javascript
Python使用Paramiko模块编写脚本进行远程服务器操作
2016/05/05 Python
Python 爬虫多线程详解及实例代码
2016/10/08 Python
详解python 拆包可迭代数据如tuple, list
2017/12/29 Python
python调用Matplotlib绘制分布点并且添加标签
2018/05/31 Python
详解pandas删除缺失数据(pd.dropna()方法)
2019/06/25 Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
2020/03/31 Python
python切片作为占位符使用实例讲解
2021/02/17 Python
HTML5拖放API实现拖放排序的实例代码
2017/05/11 HTML / CSS
宏碁西班牙官网:Acer西班牙
2021/01/08 全球购物
主要的Ajax框架都有什么
2013/11/14 面试题
自荐信的基本格式
2014/02/22 职场文书
入党自我鉴定
2014/03/25 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
2021/08/23 MySQL