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 相关文章推荐
网页常用特效代码整理
Jun 23 Javascript
经典的解除许多网站无法复制文字的绝招
Dec 31 Javascript
js使用函数绑定技术改变事件处理程序的作用域
Dec 26 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
Feb 07 Javascript
jquery通过visible来判断标签是否显示或隐藏
May 08 Javascript
jquery根据锚点offset值实现动画切换
Sep 11 Javascript
js实现超简单的展开、折叠目录代码
Aug 28 Javascript
用JS动态改变表单form里的action值属性的两种方法
May 25 Javascript
总结javascript中的六种迭代器
Aug 16 Javascript
tab栏切换原理
Mar 22 Javascript
微信小程序开发实现消息推送
Nov 18 Javascript
ECharts地图绘制和钻取简易接口详解
Jul 12 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
咖啡常见的种类
2021/03/03 新手入门
php简单实现文件或图片强制下载的方法
2016/12/06 PHP
PHP简单实现遍历目录下特定文件的方法小结
2017/05/22 PHP
php 读写json文件及修改json的方法
2018/03/07 PHP
thinkPHP3.2.3实现阿里大于短信验证的方法
2018/06/06 PHP
Yii1.1框架实现PHP极光推送消息通知功能
2018/09/06 PHP
谈谈impress.js初步理解
2015/09/09 Javascript
BootStrap智能表单实战系列(六)表单编辑页面的数据绑定
2016/06/13 Javascript
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
2018/08/20 Javascript
vue递归组件实战之简单树形控件实例代码
2019/08/27 Javascript
Vue 实现输入框新增搜索历史记录功能
2019/10/15 Javascript
Selenium执行JavaScript脚本的方法示例
2020/12/31 Javascript
[04:39]显微镜下的DOTA2第十三期—Pis卡尔个人秀
2014/04/04 DOTA
[33:17]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[40:19]2018完美盛典CS.GO表演赛
2018/12/17 DOTA
[00:06]Yes,it worked!小卡尔成功穿越时空加入战场!
2019/07/20 DOTA
[02:12]Dota 2 推出全新英雄—— 电炎绝手
2019/08/23 DOTA
Python中几个比较常见的名词解释
2015/07/04 Python
python网络编程调用recv函数完整接收数据的三种方法
2017/03/31 Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
2017/07/30 Python
解决pycharm 误删掉项目文件的处理方法
2018/10/22 Python
使用Python做垃圾分类的原理及实例代码附源码
2019/07/02 Python
解决Django 在ForeignKey中出现 non-nullable field错误的问题
2019/08/06 Python
Python SELENIUM上传文件或图片实现过程
2019/10/28 Python
美国眼镜在线零售商:Dualens
2019/12/07 全球购物
美国购买隐形眼镜网站:Lenses For Less
2020/07/05 全球购物
介绍一下常见的木马种类
2014/11/15 面试题
优秀求职自荐信怎样写
2013/12/18 职场文书
办理护照介绍信
2014/01/16 职场文书
电焊工岗位职责
2014/03/06 职场文书
卫生巾广告词
2014/03/18 职场文书
安全宣传标语口号
2014/06/06 职场文书
嘉年华活动新闻稿
2015/07/17 职场文书
创业计划书之蛋糕店
2019/08/29 职场文书
springboot集成flyway自动创表的详细配置
2021/06/26 Java/Android
十大经典日本动漫排行榜 海贼王第三,犬夜叉仅第八
2022/03/18 日漫