Skip to content

Latest commit

 

History

History
74 lines (74 loc) · 4.02 KB

闭包.md

File metadata and controls

74 lines (74 loc) · 4.02 KB

Qhappyman.github pages

每天解决一个问题发布

在线答题网站

19.2.27

理解闭包

简单的来说,什么时候形成闭包呢?大多时候当一个内部函数被保存到外部时会形成闭包.
看一段简单的代码

function test(){
  var arr = [];
  for(var i = 0;i<10;i++){
    arr[i] = function(){
      document.write(i + "");
      }
   }
   return arr;
var myarr = test();
for(var j = 0;j < 10;j++){
    myarr[j]();
 }

乍一看这一段代码的结果可能是 0 1 2 3 4 5 6 7 8 9,然而并不是,这里就涉及了闭包。
正确的打印结果是10 10 10 10 10 10 10 10 10 10
大多数人会认为当内部for循环执行时就会立即将此时的i值赋给打印值,其实并不是。
test函数执行时,每次for循环都创建了一个函数保存在arr里面,但是函数内部是什么并不知道,此时

{
     document.write(i + "");
     }

这一段代码没有立即实行,他只是告诉arr[i]里保存了一个函数,相当于创建一个arr[i] = 函数这样一个东西。当·执行到return语句时。arr这个数组被保存到外部,也就是保存了十个相同的函数,每一个都有自己的执行期上下文和作用域链,但是此时的i已经变为了10,所以虽然函数执行十次,但每次打印出来的i都是同一个.他们的作用域里面保存着test的作用域,当然i值也就是用着同一个,典型的闭包。
那么要打印出不同值怎么办,来看下面的函数

function test(){
 var arr = [];
 for(var i = 0;i<10;i++){
   (function(j){
   arr[j] = function(){
     document.write(j + "");
     }
  }(i));
 }
  return arr;
}
var myarr = test();
for(var j = 0;j < 10;j++){
   myarr[j]();
}

这一次我们给他加了一层立即执行函数,当灭磁读取到function(j)时都会立即执行一次。i作为函数的实参,j为函数的形参,此时的函数直接相互独立,形成十个不同的函数·并不会受i值变化的影响,因此会打印出来0 1 2 3 4 5 6 7 8 9
下面再来看一个函数

function add(){
   var num = 0;
   function a(){
     console.log(++num);
   }
   return a;
}
var myadd = add();
myadd();
myadd();
myadd();

这一次函数打印出来的是1 2 3。这是一个很典型的闭包。
在add函数被执行时,他形成了一个自己的AO,a函数定义是他拿的是 add的AO以及GO,并且a函数被保存到了外部。
当add函数执行完毕后他的执行期上下文被销毁,这里就容易不懂,那么既然a的2执行期上下文被销毁,那么num应该不存在了,怎么会打印出num值。
其实在a函数被保存到外部时,就已经形成了一个闭包,他的作用域链里保存着add的执行期上下文,虽然add被销毁,但是a却被保存了,导致add的执行期上下文保存在a里面而无法被释放。此时的num值已经成为了a函数所有的,不存在于add里面,当然每次执行时num不会被初始化为0,所以num值会随着a函数的的执行而改变。
总的来说,闭包就是当内部函数被保存在外部时,导致原有的内部函数上级作用域链无法被释放,跟随着内部函数被保存到外部,此时的上级作用域链里的所有东西都归内部函数所有,相当于在内部函数里面定义的变量。当多个内部函数同时形成闭包时则用的是同一个作用域,里面的东西为函数公有,当你在一个函数里面改变某一变量的值,那么在另一函数里面调用这个变量时变量值已经是改变后的数值,

闭包的坏处 :

  • 内存泄露

    其实很好理解,顾名思义,内存泄露则内存少了,闭包形成时原有作用域链没有被及时销毁,继续占用内存。就像手里握着一把沙子,沙子慢慢流出,也就是泄露,那么你手中的沙子会越来越少,内存泄漏就是这个道理。

19.2.28

js执行三部曲