IT不死旗下博客隆重开通啦,欢迎各位小伙伴们来围观 。

JS中的闭包二三事-1

Javascript Xueqi 1244℃ 0评论
闭包在JS中既是重点又是难点,很多JS的高级功能都会用到它。来看下面的例子:
<script type="text/javascript">
//例子1:
   var c=998;
   function f1(){
   var a=1;
   var b=2;
   console.log("执行函数f1");
   function f2(){
   console.log("执行f3");
   console.log("a=",a);
   console.log("b=",b);
   console.log("c=",c);
  }
   return f2;
 }
  var res=f1();
  res();


分析:当执行f1时,定义了局部变量n,b, 函数f2,然后又把函数f2返回,并且用变量
res接收。整个f1函数执行完毕,正常流程应该是这个执行环境就销毁了,里面的局部变量
都销毁了,但是这里返回了函数f2,外部变量引用了f2,f2又用到了f1函数里的变量a,b
所以f1的整个执行环境都保留了下来,(这些变量的值始终保持在内存中)下次执行的时候,f2里输出a,b,它里面没有定义,
根据作用域链,它在f1里找到了变量a,b,在全局中找到了c,所以就输出了。代码中的f2就是闭包




</script>
例子2:
<script type="text/javascript">
 function f1(){
   var n=2;
   nAdd=function(){
   n=n+1;
   cosnole.log("nAdd执行了");
}
 function f2(){
   console.log(n);
 }
   return f2;
}
  var res=f1();
  res(); //2
  nAdd();//nAdd执行了
  nAdd();//nAdd执行了
  nAdd();//nAdd执行了
  res(); //5
  

res实际上就是闭包f2函数。它一共运行了两次,第一次的运行后n的值变为3,第二次运行后n的值变为4。这说明,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。
这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数,而这个
匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。


闭包通俗一些的理解:

当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,
当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们.
七、Javascript的垃圾回收机制

在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。
如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
</script>

转载请注明:凌风阁 » JS中的闭包二三事-1

喜欢 (9)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址