让前端飞Web前端之路JavaScript 进阶营

闭包——十万个为什么

2019-08-08  本文已影响10人  DIV豪

什么是闭包?

简单的来说闭包就是函数。那函数是不是闭包呢?

网上有一句话js函数皆是闭包。我觉得这句话是不太准确。我们先这直接忽略这个说法

先来看下 相对官方说法:闭包是指有权访问另一个函数作用域中的变量的函数                                                         

看到这据话有点懵,所以我们拆解下变成 ————闭包是指有权访问另一个(函数作用域中的)变量的函数

在换成我的理解:闭包就是函数嵌套函数,里面的函数引用外面函数的变量。

什么是函数嵌套函数?

举个粟子1

function fun1(){

  function fun2(){

        {

}

什么是里面的函数引用外面函数的变量。

举个粟子2

function fun1(){

      var n=10;

      function fun2(){

          console.log(n);//这里的n没声明,使用的是上级作用域fun1的n

      }

  }

{友情提示基础比较好的可以直接跳到下面看    闭包的超级简单粟子}

闭包有什么特性?

闭包有三个特性
函数嵌套函数
函数内部可以引用外部的参数和变量
参数和变量不会被垃圾回收机制回收

函数嵌套函数这个在粟子1中已经说了

函数内部可以引用外部的参数和变量在粟子2也说了
参数和变量不会被垃圾回收机制回收这个又是什么意思呢?

闭包不也是函数吗?这么可能不会被回收呢?而且不是说

局部变量会在函数完成时被删除吗?

我们先带着这个疑问,做几道题

带着 在函数开始时会创建局部变量,在函数完成时会删除它们 这个问题看下面代码。

也就是说函数没调用前只是声明跟定义,并木有被创建,等到调用了才创建(换句话说如果没被调用就相当于function fun(){},调用才创建里面的代码)

有人问为什么代码被销毁了第二个fun1();还可以调用?那是因为函数在调用时候才往里面加代码

如果还不理解,那就换个比喻,假如有一个盒子1,放在上面,没调用之前,我放着,调用时,我拿东西装进去,调用完,我就扔掉这个盒子1里面的东西;然后在第二次调用之前,我用盒子1在把里面的东西装进去,调用时,我继续放东西进去,调用后我继续扔掉盒子东西。

我们在看下面代码

为什么第二个fun1();控制台输出的是12?

这里有一个陷阱,a++ 没有在局部变量声明所以用的是全局变量的a所以会改变全局变量 var a = 10的值 变成var a = 11 ;(全局变量会在您关闭页面是被删除。)

还要肯定一件事就是第一个fun1()调用后完成后就销毁。
调用第二个fun1()时;全局变量的var a = 11;所以控制台输出是12;

了解了上面两个代码后我们在看一下

闭包的超级简单粟子

从这个粟子中我们可以fun1();也是会销毁的,不过是要等到内部函数结束后才销毁,所以利用这个特点就产生了闭包这种说法。

在回顾下 参数和变量不会被垃圾回收机制回收这句话

这句话我觉得也有点毛病 应该说这是一个相对于谁的问题,是暂时不会被回收。

最后在说下 闭包的目的和优缺点

目的:使用闭包主要是为了设计私有的方法和变量。

闭包的优点是可以避免全局变量的污染,

缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄漏。

在在在最后,在顺便了解下JavaScript垃圾回收的机制(了解懂吧,就了解就行啦)

JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存

什么叫不再使用的变量?

不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后再函数中使用这些变量,直至函数结束(闭包中由于内部函数的原因,外部函数并不能算是结束)

结尾什么是闭包

闭包是指:有权访问另一个 函数作用域中的 变量的函数

上面这话如何理解--------我的理解:闭包就是函数嵌套函数,里面的函数引用外面函数的变量。

上一篇下一篇

猜你喜欢

热点阅读