说一说js中的闭包

不说官方给的定义,感受本身刚开始看也不是很理解。闭包

闭包 : 其实就是 该函数能使用函数外定义的变量。函数

 

为何要使用闭包?spa

首先来讲一下局部变量和全局变量的危害: 全局变量容易全局污染,局部变量又没法共享,不能长久保存code

那闭包实现了一个什么?对象

既能够共享,长久保存,又不会全局污染,实际上是用来保护局部变量的。blog

闭包有什么缺点?内存

占内存,至于为何占内存,稍后会画内存图来讲明。作用域

 

若是说你要写一个闭包,就是抓住闭包的三个特色:get

  1. 定义外层函数,封装被保护的局部变量
  2. 定义内层函数,执行对局部变量(外层函数的)的操做
  3. 外层函数返回内层函数的对象,而且外层函数被调用,结果保存在全局变量中
function outer(){
   var n = 1;
   function inner(){
       return  n++;
   }  
   return inner;
}
var getNum = outer();

 

因此说在你判断闭包的时候通常是看如下三点:io

  1. 嵌套函数
  2. 内层函数必定操做了外层函数的局部变量
  3. 外层函数将内层函数返回到外部,被全局变量保存住

那一个闭包咱们又如何去判断他的执行结果呢?

  1. 外层函数被调用了几回,就有几个受保护的局部变量副本
  2. 来自一个闭包的函数被调用几回,受保护的局部变量就变化几回

好比刚刚那个例子来讲:

function outer(){
   var n = 1;
   function inner(){
       return  n++;
   }  
   return inner;
}
var getNum = outer();
//外层函数调用一次,有一个被保护的n
console.log(getNum());
//0
console.log(getNum());
//1
var getNum2 = outer();
//外层函数被调用两次,有两个互不干扰的n
console.log(getNum2());
//0

内存图:

  建立函数的同时会建立两个对象:  

        函数对象:函数的定义  (老板)

        做用域链对象:保存了函数对象可用的变量的位置的对象(栈),默认第一项指向window(管理员)

  而调用函数时,又会建立一个新对象

        活动对象:专门保存局部变量的对象(这里说一下函数中的局部变量指的是  参数  和  var声明的)

        在做用域链对象中追加指向活动对象的引用

  调用后:仅仅释放了活动对象,做用域链中活动对象的引用出栈,活动对象因无人引用而释放

      (也就是说内存图中,某一块当没有人指入它时,就会被释放)

 

 除去释放后的部分:

 

可见若是有闭包的存在,实际上是很占内存的,它会造成这种循环的指入,使得没法被释放

相关文章
相关标签/搜索