我对闭包的理解,非常浅显易懂

320 阅读3分钟

blog.csdn.net/ef_ef/artic… 迁移的文章,傻逼csdn把我号封了

好像我的理解有点问题,但是这篇文章写了这么多了,就不舍得删掉了,就这样吧。

前言

这篇文章有些东西都是我自己的猜测,百度也百度不到,也可能是我不太会百度...希望有懂的人能反驳一下。 但是我觉得这篇文章用来学习闭包还是挺不错的,至少很浅显易懂。

总结

  1. 闭包是编程语言的特性(编程语言中函数的特性),有些编程语言是支持闭包的,比如js的函数就是闭包的,有些语言不是闭包的,额我也不知道有哪些...
  2. 函数执行时,函数体内访问的变量是从函数声明位置往外寻找的,就是闭包;相反,函数执行时,函数体内访问的变量是从函数调用位置往外寻找的,就是不闭包
  3. 闭包和不闭包对编程语言的影响主要在于: 要不要把函数的形参或变量当成垃圾进行垃圾回收

闭包是个什么鬼

首先再强调一下,js是闭包的。 在这里插入图片描述转化成函数就是下面这样:

  let innerFun;
  let a = 1;
  function outterFun() {
    let a = 2;
    innerFun = function() { // (*)
      console.log(a);
    }
  }
  outterFun();
  innerFun();

控制台打印的是2而不是1,至于原因是什么,你可以这么理解:innerFun这个函数声明在(*)行,所以这个a要从(*)行所在的外部作用域往外找,这个作用域里面刚好有a,且a=2,就不用继续往外查找了,它不可能找到第二行的a=1,所以控制台打印的就是2。

我上面说的,a是从innerFun函数声明的位置往外找的,注意:这里的重点是函数声明的位置!!! 这就是闭包的重点------函数执行时,函数体内访问的变量是从函数声明位置往外寻找的,就是闭包。

不闭包又是什么鬼

那有闭包,肯定就有不闭包,不闭包又是怎么样的呢,我就有下面这样的猜测:

  let innerFun;
  let a = 1;
  function outterFun() {
    let a = 2;
    innerFun = function() {
      console.log(a);
    }
  }
  outterFun();
  innerFun(); // (*)

还是同样的代码,假设js是不闭包的语言,那这个a就应该是从函数执行的位置开始往外查找的吧(只是猜测),函数执行的位置在(*)行,那么往外查找到的第一个a就是在第二行,所以a=1,控制台就应该输出1。

函数执行时,函数体内访问的变量是从函数调用位置往外寻找的,就是不闭包。

闭包与不闭包的区别: 垃圾回收

闭包是从函数声明处查找变量的,而且我们知道,只要变量还有机会被使用到就不会被垃圾回收,那么外部函数outterFun即使执行完,内部变量a依旧能被使用,所以a就不会被当做垃圾被回收。

相反,不闭包的话,a就会被垃圾回收。

总结

  1. 闭包是编程语言的特性(编程语言中函数的特性),有些编程语言是支持闭包的,比如js的函数就是闭包的,有些语言不是闭包的,额我也不知道有哪些...
  2. 函数执行时,函数体内访问的变量是从函数声明位置往外寻找的,就是闭包;相反,函数执行时,函数体内访问的变量是从函数调用位置往外寻找的,就是不闭包
  3. 闭包和不闭包对编程语言的影响主要在于: 要不要把函数的形参或变量当成垃圾进行垃圾回收