JavaScript闭包和回调详解


Posted in Javascript onAugust 09, 2017

一、闭包

 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

闭包有三个特性:

1.函数嵌套函数;

2.函数内部可以引用外部的参数和变量;

3.参数和变量不会被垃圾回收机制回收。

 闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。使用闭包有一个优点,也是它的缺点,就是可以把局部变量驻留在内存中,可以避免使用全局变量。全局变量在每个模块都可调用,这势必将是灾难性的。所以推荐使用私有的,封装的局部变量。一般函数执行完毕后,局部活动对象就被销毁,内存中仅仅保存全局作用域。但闭包的情况不同!

 示例一:

//闭包就是一个函数的返回值为另外一个函数,在outer外部可以通过这个返回的函数访问outer内的局部变量.

function outer(){
 var val = 0;
 return function (){
  val += 1;
  document.write(val + "<br />");
 };
}
var outObj = outer();
outObj();//1,执行val += 1后,val还在
outObj();//2
outObj = null;//val 被回收
var outObj1 = outer();
outObj1();//1
outObj1();//2

闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗(如果上例中定义很多outer(),则内存中会保存很多val变量)。

javascript的垃圾回收原理:

 (1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;

 (2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。

 那么使用闭包有什么好处呢?使用闭包的好处是:

1.希望一个变量长期驻扎在内存中

2.避免全局变量的污染

3.私有成员的存在

二、回调

 回调函数原理:我现在出发,到了通知你”。这是一个异步的流程,“我出发”这个过程中(函数执行),“你”可以去做任何事,“到了”(函数执行完毕)“通知你”(回调)进行之后的流程。

 示例一:

function doSomething(callback){
 callback(1,2);
}
function numberAdd(a,b){
 document.write(a+b);
}
doSomething(numberAdd);//3

示例二:

function Thing(name){
 this.name = name;
}

//在Thing类里加入doSomething方法,这里使用了构造器调用模式

Thing.prototype.doSomething = function(callback){
 callback(this.name);
};
function showName(name){
 document.write(name);
}
var t = new Thing("zhangsan");
t.doSomething(showName);//zhangsan

如果你有一个数字组成的数组,你想写个排序的公共方法,但是排序方式(从小到大或从大到小)是调用该排序方法的人决定。实现该排序方法可以用回调来实现,当然你可以写2个方法,一个是从小到大的排序,一个是从大到小的排序方法。回调个人认为就是将决定权交给了实际业务开发工程师,由他来决定怎么去处理,这种思路跟我们平常接触的不同,有点不习惯,但是这种思路在异步编程中特别能看出它的好处,不知道我这么理解是否正确。下面示例代码就是回调的典型使用场合:

var arr = [25,13,33,8,23,32];
Array.prototype.sort = function(callback){
 var arr = this;
 var i = 0;//i在这里定义与在for循环的括号内(for(var i = 0; i < ...))定义是一样的
 for(; i < arr.length-1; i++){
  var j = i + 1;
  for(; j < arr.length;j++){
  if(callback(arr[i],arr[j])){
   var temp = arr[i];
   arr[i] = arr[j];
   arr[j] = temp;
  }
  } 
 }
return arr;
};
//a-b>0表示数组从小到大排序
arr.sort(function(a,b){
 return a - b > 0;
});
document.write(arr.join(",") + "<br />");//8,13,23,25,32,33
//b-a>0表示数组从大到小排序
arr.sort(function(a,b){
 return b - a > 0;
});
document.write(arr.join(","));//33,32,25,23,13,8

Javascript 相关文章推荐
Prototype Selector对象学习
Jul 23 Javascript
JS 实现双色表格实现代码
Nov 24 Javascript
Javascript 面向对象 继承
May 13 Javascript
javascript实现的DES加密示例
Oct 30 Javascript
js实现按钮加背景图片常用方法
Nov 01 Javascript
简单理解JavaScript中的封装与继承特性
Mar 19 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
浅谈Node.js:理解stream
Dec 08 Javascript
理解 javascript 中的函数表达式与函数声明
Jul 07 Javascript
自制简易打赏功能的实例
Sep 02 Javascript
vue、react等单页面项目应该这样子部署到服务器
Jan 03 Javascript
layui实现数据表格点击搜索功能
Mar 26 Javascript
ionic 3.0+ 项目搭建运行环境的教程
Aug 09 #Javascript
JavaScript实现的浏览器下载文件的方法
Aug 09 #Javascript
Node.js五大应用性能技巧小结(必须收藏)
Aug 09 #Javascript
详解用node搭建简单的静态资源管理器
Aug 09 #Javascript
vue页面使用阿里oss上传功能的实例(二)
Aug 09 #Javascript
vue.js框架实现表单排序和分页效果
Aug 09 #Javascript
vue页面使用阿里oss上传功能的实例(一)
Aug 09 #Javascript
You might like
落伍首发 php+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
2006/12/16 PHP
PHP写UltraEdit插件脚本实现方法
2011/12/26 PHP
使用PHP接收POST数据,解析json数据
2013/06/28 PHP
详解php中空字符串和0之间的关系
2016/10/23 PHP
PHP中cookie知识点学习
2018/05/06 PHP
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
JQuery select(下拉框)操作方法汇总
2015/04/15 Javascript
js实现n秒倒计时后才可以点击的效果
2015/12/20 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
简单实现jQuery弹幕效果
2017/05/06 jQuery
BootStrap实现文件上传并带有进度条效果
2017/09/11 Javascript
vue前后分离调起微信支付
2019/07/29 Javascript
js实现指定时间倒计时效果
2019/08/26 Javascript
jQuery实现滑动星星评分效果(每日分享)
2019/11/13 jQuery
js实现浏览器打印功能的示例代码
2020/07/15 Javascript
详解vue路由
2020/08/05 Javascript
[01:09]DOTA2次级职业联赛 - ishow.HMM战队宣传片
2014/12/01 DOTA
python使用pil生成图片验证码的方法
2015/05/08 Python
python 文件操作删除某行的实例
2017/09/04 Python
Python实现曲线点抽稀算法的示例
2017/10/12 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
Flask框架Jinjia模板常用语法总结
2018/07/19 Python
Python 数据库操作 SQLAlchemy的示例代码
2019/02/18 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
使用python执行shell脚本 并动态传参 及subprocess的使用详解
2020/03/06 Python
使用python接受tgam的脑波数据实例
2020/04/09 Python
keras 获取某层的输入/输出 tensor 尺寸操作
2020/06/10 Python
基于Python爬取fofa网页端数据过程解析
2020/07/13 Python
Python直接赋值及深浅拷贝原理详解
2020/09/05 Python
python利用tkinter实现图片格式转换的示例
2020/09/28 Python
如何设定的weblogic的热启动模式(开发模式)与产品发布模式
2012/09/08 面试题
教师职称自我鉴定
2014/02/12 职场文书
勤俭节约演讲稿
2014/05/08 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
Python中super().__init__()测试以及理解
2021/12/06 Python
Nginx 502 bad gateway错误解决的九种方案及原因
2022/08/14 Servers