一、闭包概念
闭包:有权访问另一个函数作用域中的变量的函数;一般情况就是在一个函数中包含另一个函数。
从官方定义我们知道闭包是一个函数,只不过这个函数有[超能力],可以访问到另一个函数的作用域。
为什么说这个叫做[超能力]呢?
因为我们知道函数作用域是独立的、封闭的,外部的执行环境是访问不了的,但是闭包具有这个能力和权限。
那闭包是怎样的一个表现形式呢?
第一,闭包是一个函数,而且存在于另一个函数当中
第二,闭包可以访问到父级函数的变量,且该变量不会销毁
1 | function person() { |
二、闭包原理
闭包的实现原理,其实是利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层也就是全局作用域,这样就形成了一个链条。
例如:
1 | var age = 18; |
看到这里,大家都会说这不就是最简单的函数和变量形式吗?闭包在哪里?别急,我们接着往下看:
如果我们再次调用时,结果会一直增加,也就变量 age 的值一直递增。
1 | cat(); //20 |
如果程序还有其他函数,也需要用到 age 的值,则会受到影响,而且全局变量还容易被人修改,比较不安全,这就是全局变量容易污染的原因,所以我们必须解决变量污染问题,那就是把变量封装到函数内,让它成为局部变量。
1 | function person() { |
这里又出现问题了,每次调用函数 person,进入该作用域,变量 age 就会重新赋值为 18,所以 cat 的值一直是 19;所以需要做一下调整:
1 | var per = person(); //per相当于函数cat |
而且变量 age 在函数内部,不易修改和外泄,相对来说比较安全。
三、闭包作用
作用 1:隐藏变量,避免全局污染
作用 2:可以读取函数内部的变量
同时闭包使用不当,优点就变成了缺点:
缺点 1:导致变量不会被垃圾回收机制回收,造成内存消耗
缺点 2:不恰当的使用闭包可能会造成内存泄漏的问题
这里简单说一下,为什么使用闭包时变量不会被垃圾回收机制收销毁呢,这里需要了解一下 JS 垃圾回收机制;
JS 规定在一个函数作用域内,程序执行完以后变量就会被销毁,这样可节省内存;
使用闭包时,按照作用域链的特点,闭包(函数)外面的变量不会被销毁,因为函数会一直被调用,所以一直存在,如果闭包使用过多会造成内存销毁。
四、闭包应用
需求:实现变量 a 自增
1、通过全局变量,可以实现,但会污染其他程序
1 | var a = 10; |
2、定义一个局部变量,不污染全局,但是实现不了递增
1 | var a = 10; |
3、通过闭包,可以是函数内部局部变量递增,不会影响全部变量,完美!!
1 | var a = 10; |
- Post link: https://blog.gaocaipeng.com/2020/03/02/hwizmv/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.