js闭包和回调

1、闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
闭包有三个特性:
1.函数嵌套函数;
2.函数内部可以引用外部的参数和变量;
3.参数和变量不会被垃圾回收机制回收。
闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。使用闭包有一个优点,也是它的缺点,就是可以把局部变量驻留在内存中,可以避免使用全局变量。全局变量在每个模块都可调用,这势必将是灾难性的。所以推荐使用私有的,封装的局部变量。一般函数执行完毕后,局部活动对象就被销毁,内存中仅仅保存全局作用域。但闭包的情况不同!
示例一:
//闭包就是一个函数的返回值为另外一个函数,在outer外部可以通过这个返回的函数访问outer内的局部变量.

 1 function outer(){
 2      var val = 0;
 3      return function (){
 4            val += 1;
 5            document.write(val + "<br />");
 6      };
 7 }
 8 var outObj = outer();
 9 outObj();//1,执行val += 1后,val还在
10 outObj();//2
11 outObj = null;//val 被回收
12 var outObj1 = outer();
13 outObj1();//1
14 outObj1();//2

闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗(如果上例中定义很多outer(),则内存中会保存很多val变量)。
javascript的垃圾回收原理:
(1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
(2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
那么使用闭包有什么好处呢?使用闭包的好处是:
1.希望一个变量长期驻扎在内存中
2.避免全局变量的污染
3.私有成员的存在



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

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

示例二:

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

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

1 Thing.prototype.doSomething = function(callback){
2    callback(this.name);
3 };
4 function showName(name){
5    document.write(name);
6 }
7 var t = new Thing("zhangsan");
8 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
时间: 2024-10-29 19:06:30

js闭包和回调的相关文章

大部分人都会做错的经典JS闭包面试题

大部分人都会做错的经典JS闭包面试题 目录 由工作中演变而来的面试题 JS中有几种函数 创建函数的几种方式 三个fun函数的关系是什么? 函数作用域链的问题 到底在调用哪个函数? 后话 由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,

js闭包浅了解

js闭包浅理解 要理解闭包,得先知道js的变量作用域,在js中,有两种变量作用域: 全局作用域 局部作用域 一.在函数内可以访问全局变量 比如,下面的例子: <!--lang:js--> <script> var n = 100; function f1(){ console.log(n); } f1()//返回100 </script> 上面的例子很简单,下面是另一种情况. 二.在函数外无法读取函数内的局部变量 还是一个小例子: <!--lang:js-->

js闭包的作用

js闭包的用途详解 js闭包可以用在许多地方.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中.具体怎么理解呢,各位看官请仔细看好下文 我们来看看闭包的用途.事实上,通过使用闭包,我们可以做很多事情.比如模拟面向对象的代码风格:更优雅,更简洁的表达出代码:在某些方面提升代码的执行效率. 1 匿名自执行函数 我们知道所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处,比如:别的函数可能误用

浅谈JS闭包中的循环绑定处理程序

初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 前几天工作中写前端js代码时,遇到了遍历元素给它添加单击事件. (PS:之前也在<jQuery基础教程>第四版中看过讲循环绑定处理程序的内容,当时估计也没怎么用心看,所以没记起来.) 大神要是知道这类情况,可以关掉窗口,写这些主要是给像我一样的小白看的,谢谢! 先贴上错误的例子让大家

关于JS闭包,作者不详(转)

说明:本文由两篇文章结合而成,系从他人笔记中转过来的, 具体作者不详.因为觉得不错,遂共享之.如有侵权,立删致歉. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 fun

js闭包(closure),个人理解

一.闭包概念理解 各种专业文献上对js"闭包"(closure)定义非常抽象,贼难看懂.我的理解是,闭包就是能够读取某函数内部变量的函数.由于在Javascript语言中只有在函数内部的函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数".所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁. 二.用途 闭包可以用在很多地方.但它最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中. 三.使

node.js如何使用回调

Node.js到处使用回调,尤其在有I/O(输入/输出)操作的地方. 下面是在一个Node.js中使用filesystem模块中从磁盘上读入文件内容示例一: var fs = require('fs'); fs.redFile('somefile.txt', 'urf8', function (err, data) { if (err throw err); console.log(data); }); 以下是所发生的事情: 1.fs(filesystem)模块被请求,以便在脚本中使用 2.将文

【ThinkingInJava】18、 关于java中的闭包与回调

/** * 书本:<Thinking In Java> * 功能:关于java中的闭包与回调,这里回调区别于C++,C++中回调的话寄托于指针 * 文件:Callbacks.java * 时间:2015年4月3日20:26:43 * 作者:cutter_point */ package Lession10innerclasses; import static net.mindview.util.Print.*; //创建一个接口,包含一个函数 interface Incrementable {

理解js闭包原理

各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂.我的理解是,闭包就是能够读取其他函数内部变量的函数. 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数". 所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁. 闭包可以用在许多地方.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中. 怎么来理解这句话呢?请看下面的