了解javascript闭包是什么?

闭包closure有两个特点:

(1)闭包是一个函数的局部变量 - 函数返回后它还活着

(2)闭包是一个函数,返回时内存堆栈帧不会被释放,不会被垃圾回收。


第一个例子:

 

 function sayHello(name){
   var text='Hello'+name; //local variable局部变量
   var sayAlert=function() {
     alert(text);
   }
   return sayAlert;
  }

 var say2=sayHello("World");
  say2();

上面的sayAlert是一个sayHello函数的局部变量,sayHello返回的是sayAlert,传给了 say2,sayAlert 和say2 实际指向也就是Hold的是同一个函数,这个函数在这里是一个匿名函 数 function() { alert(text); },因为这个匿名函数被外部Hold住了,所以它不 会被垃圾回收,不会从内存中消失。因为这个匿名函数存在sayHello中,是其一部分,因此sayHello也不会消失,因而sayHello中任何元 素都不会消失,比如sayHello中一个局部变量var text就不会消失。这点是与我们一般对象的方法认识不同的,只要是对象方法中的局部变量,该方法被调用完就丢弃,从内存中消失。

何以见得sayHello中一个局部变量var text不会消失呢?因为我们在上面最后一行调用say2()时,并没有任何赋值行为,但是调出的效果还是Hello Jdon,而不是Hello null。因为调用say2(),实际就是执行匿名函数 function() { alert(text); },而alert(text)中调用本地变量text的值,text的值是Hello Jdon。注意的是,这个text属于一旦被赋值就不再改变,是一个不变性质的量,在Java语言中是要用final修饰符的。

  

当你在一个函数中又使用了另外一个函数时,你在创建一个闭包。


深入案例

 为了了解上面闭包造成var text被Hold在内存中的效果,再看源码,有两个函数foo和foo2:
  function foo(x) {
   var tmp = 3;
   return function (y) {
     alert(x + y + (++tmp));
   }
  }
  var bar = foo(2); // bar现在是一个闭包
  bar(10);
  bar(10);
  bar(10);

  上面我们执行了三次bar(10),结果是16 17 和18,每次结果不一样,因为var tmp这个变量一直存在内存,++tmp是每次累计上次的值,自增。所以,结果不断累积+1。

  下面foo2函数不是一个闭包,无论调用几次结果总是16,因为tmp局部变量每次在函数被调用时都是从3开始。

 function foo2(x) {
  var tmp = 3;
  function bar2(y) {
   alert(x + y + (++tmp));
  }
  bar2(10);
 }
 foo2(2);
 foo2(2);
 foo2(2)

函数用作全局变量

  由于一个函数中的局部变量生存周期只是在一个函数体内,如果我们想将这个局部变量变成全局变量,那么通过函数方法实现对这个局部变量的操作即可,按照面向对象的思路来看,这个局部变量实际是一个可变变量,是一个状态,必须通过自身的方法来操作它,而不是直接将其暴露给外界,任由外界作为全局变量蹂躏。

  下面setupSomeGlobals代码是通过几个函数改变其内部变量num,如果你想给num增加,那么调用gIncreaseNumber方法,然后再调用gAlertNumber(),看看结果是否增加。

 function setupSomeGlobals() {
   // Local variable that ends up within closure
   var num = 666;
   // Store some references to functions as global variables
   gAlertNumber = function() { alert(num); }
   gIncreaseNumber = function() { num++; }
   gSetNumber = function(x) { num = x; }
 }

 setupSomeGlobals();
 gAlertNumber();
 gIncreaseNumber();
 gAlertNumber();
 gSetNumber(-100);
 gAlertNumber();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值