javascript中闭包(Closure)详解


Posted in Javascript onJanuary 06, 2016

在javascript中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中。

var fun = function(){
  console.log("平底斜");
}
function fun(){
  var n=10;
  function son(){
    n++;
  }
  son();
  console.log(n);
}
fun(); //11
fun(); //11

我们把上面第二段代码稍微修改下:

var n=10;
function fun(){
  function son(){
    n++;
  }
  son();
  console.log(n);
}
fun(); //11
fun(); //12

看出差别了吗,如果理解不了代码执行结果,请看上一篇博文,关于javascript作用域和作用域链的讲解。

上面这段代码中变量n是全局变量,随时可能被重新赋值,而无需通过fun函数的调用。为了让变量n不受污染,或者说是减少全局变量的污染,我们需要把n放到函数中作为局部变量。

function fun(){
  var n=10;
  function son(){
    n++;
    console.log(n);
  }
  son();
}
fun(); //11
fun(); //11

如果我们可以在全局中直接调用son函数,那么便可以达成想要的效果。son函数现在是作为局部变量存在,要想在全局中访问,一般有两种方法:

一种是赋值给全局变量

var a;
function fun(){
  var n=10;
  a = function son(){
    n++;
    console.log(n);
  }
}
fun(); //son()
a(); //11
a(); //12

另一种是使用return返回值

function fun(){
  var n=10;
  return function son(){
    n++;
    console.log(n);
  }
}
var a=fun();
a(); //11
a(); //12

上面的son()函数就是闭包,某种意义上所有函数都可以看作闭包。闭包就是可以访问外层函数作用域的变量的函数。

var a;
function fun(){
  var n=10;
  a = function son(){
    n++;
    console.log(n);
  }
  return a();
}
fun(); //11
a(); //12
a(); //13
fun(); //11
a(); //12
a(); //13

还是上面那段代码,我们稍微修改下,再看看执行结果,这是因为每次执行fun()函数时都会初始化变量n。

闭包的好处是减少全局变量,避免全局污染,可以将局部变量保存在内存中。但这既是优点又是缺点,一段代码中如果闭包过多,有可能造成内存泄露。由于闭包中局部变量不会被垃圾回收机制回收,所以需要手动赋值为null(关于内存泄露,后期单独开专题)

Javascript 相关文章推荐
学习YUI.Ext 第六天--关于树TreePanel(Part 1)
Mar 10 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
Mar 01 Javascript
js window.open弹出新的网页窗口
Jan 16 Javascript
js代码验证手机号码和电话号码是否合法
Jul 30 Javascript
微信小程序 教程之模块化
Oct 17 Javascript
Vue.js如何优雅的进行form validation
Apr 07 Javascript
Vue实现typeahead组件功能(非常靠谱)
Aug 26 Javascript
详解如何让Express支持async/await
Oct 09 Javascript
vue.js项目打包上线的图文教程
Nov 16 Javascript
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
Apr 19 Javascript
Node.js中你不可不精的Stream(流)
Jun 08 Javascript
教你如何用Node实现API的转发(某音乐)
Sep 20 Javascript
果断收藏9个Javascript代码高亮脚本
Jan 06 #Javascript
基于HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
Jan 05 #Javascript
JavaScript实现简单的tab选项卡切换
Jan 05 #Javascript
javascript实现简单的全选和反选功能
Jan 05 #Javascript
Javascript原型链的原理详解
Jan 05 #Javascript
深入浅析JavaScript系列(13):This? Yes,this!
Jan 05 #Javascript
基于javascript实现图片懒加载
Jan 05 #Javascript
You might like
php的header和asp中的redirect比较
2006/10/09 PHP
php实现邮件发送并带有附件
2014/01/24 PHP
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
2016/03/07 PHP
JQuery 网站换肤功能实现代码
2009/11/02 Javascript
JS常用正则表达式总结
2013/11/12 Javascript
js动态创建上传表单通过iframe模拟Ajax实现无刷新
2014/02/20 Javascript
javascript生成随机数的方法
2014/05/16 Javascript
javascript中alert()与console.log()的区别
2015/08/26 Javascript
JavaScript脚本判断蜘蛛来源的方法
2015/09/22 Javascript
js实现选中页面文字将其分享到新浪微博
2015/11/05 Javascript
详解AngularJS控制器的使用
2016/03/09 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
2016/03/17 Javascript
原生javascript实现图片放大镜效果
2017/01/18 Javascript
js 函数式编程学习笔记
2017/03/25 Javascript
react native 获取地理位置的方法示例
2018/08/28 Javascript
微信小程序性能优化之checkSession的使用
2019/03/06 Javascript
详解微信小程序scroll-view横向滚动的实践踩坑及隐藏其滚动条的实现
2019/03/14 Javascript
JavaScript中的ES6 Proxy的具体使用
2019/06/16 Javascript
js 数据类型判断的方法
2020/12/03 Javascript
[04:59]DOTA2-DPC中国联赛 正赛 Ehome vs iG 选手采访
2021/03/11 DOTA
Python版微信红包分配算法
2015/05/04 Python
使用python实现knn算法
2017/12/20 Python
python中的字典操作及字典函数
2018/01/03 Python
Django如何实现网站注册用户邮箱验证功能
2019/08/14 Python
部署Django到阿里云服务器教程示例
2020/06/03 Python
django 模型字段设置默认值代码
2020/07/15 Python
CSS中几个与换行有关的属性简明总结
2014/04/15 HTML / CSS
HTML5在canvas中绘制复杂形状附效果截图
2014/06/23 HTML / CSS
html5视频自动横过来自适应页面且点击播放功能的实现
2020/06/03 HTML / CSS
世界首屈一指的在线男士内衣权威:HisRoom
2017/08/05 全球购物
Brydge英国:适用于Apple iPad和Microsoft Surface Pro的蓝牙键盘
2019/05/16 全球购物
2014年有孩子的离婚协议书范本
2014/10/08 职场文书
加强作风建设工作总结
2014/10/23 职场文书
2014年生产部工作总结
2014/12/17 职场文书
销售合作意向书范本
2015/05/08 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书