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 相关文章推荐
textarea中的手动换行处理的jquery代码
Feb 26 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
Mar 04 Javascript
JS数组的赋值介绍
Mar 10 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
May 12 Javascript
js 采用delete实现继承示例代码
May 20 Javascript
React Native预设占位placeholder的使用
Sep 28 Javascript
JS使用tofixed与round处理数据四舍五入的区别
Oct 25 Javascript
手把手教你使用vue-cli脚手架(图文解析)
Nov 08 Javascript
webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)
Jan 09 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
May 01 Javascript
如何实现vue的tree组件
Dec 03 Vue.js
Vuex实现简单购物车
Jan 10 Vue.js
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
用 Composer构建自己的 PHP 框架之构建路由
2014/10/30 PHP
PHP实现的二分查找算法实例分析
2017/12/19 PHP
namespace.js Javascript的命名空间库
2011/10/11 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
2013/12/10 Javascript
js使用递归解析xml
2014/12/12 Javascript
60个很实用的jQuery代码开发技巧收集
2014/12/15 Javascript
jQuery插件开发精品教程(让你的jQuery更上一个台阶)
2015/11/07 Javascript
浅析Javascript ES6新增值比较函数Object.is
2016/08/24 Javascript
jQuery实现的checkbox级联选择下拉菜单效果示例
2016/12/26 Javascript
vue.js+Element实现表格里的增删改查
2017/01/18 Javascript
vue实现文章内容过长点击阅读全文功能的实例
2017/12/28 Javascript
javascript实现遮罩层动态效果实例
2019/05/14 Javascript
vue实现防抖的实例代码
2021/01/11 Vue.js
[01:56]2014DOTA2西雅图邀请赛 MVP外卡赛老队长精辟点评
2014/07/09 DOTA
[01:51]2018年度CS GO最具人气外援-完美盛典
2018/12/16 DOTA
python常见数制转换实例分析
2015/05/09 Python
Python通过90行代码搭建一个音乐搜索工具
2015/07/29 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
django之跨表查询及添加记录的示例代码
2018/10/16 Python
python使用pipeline批量读写redis的方法
2019/02/18 Python
Django web框架使用url path name详解
2019/04/29 Python
python操作openpyxl导出Excel 设置单元格格式及合并处理代码实例
2019/08/27 Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
2021/01/26 Python
深入理解HTML5定时器requestAnimationFrame的使用
2018/12/12 HTML / CSS
New Balance法国官方网站:购买鞋子和服装
2019/09/01 全球购物
公司董事长职责
2013/12/12 职场文书
优秀的自荐信要注意哪些
2014/01/03 职场文书
期末自我鉴定
2014/02/02 职场文书
《尊严》教学反思
2014/02/11 职场文书
项目采购员岗位职责
2014/04/15 职场文书
企业介绍信范文
2015/01/30 职场文书
2015学校师德师风工作总结
2015/04/22 职场文书
2019大学生暑期实习心得总结
2019/08/21 职场文书
MYSQL数据库使用UTF-8中文编码乱码的解决办法
2021/05/26 MySQL
2021年国产动漫公司排行前十名,玄机科技上榜,第二推出过铠甲勇士
2022/03/18 杂记
win10识别不了U盘怎么办 win10系统读取U盘失败的解决办法
2022/08/05 数码科技