闭包的借鉴以及自我理解

闭包

1. 准备

在理解闭包之前,有个重要的概念需要先了解一下,就是 js 执行上下文。

当代码在JavaScript中运行时,执行代码的环境非常重要,并将概括为以下几点:

全局作用域——第一次执行代码的默认环境。

函数作用域——当执行流进入函数体时。

我们当作 执行上下文 是当前代码执行的一个环境与作用域。

什么是闭包

闭包是 js 创建函数就自带的一种机制

  • 它是这样工作的,无论何时声明新函数并将其赋值给变量,都要存储函数定义和闭包。闭包包含在函数创建时作用域中的所有变量,它类似于背包。

    函数定义附带一个小背包,它的包中存储了函数定义创建时作用域中的所有变量。

案例

 1: function createCounter() {
 2:   let counter = 0
 3:   const myFunction = function() {
 4:     counter = counter + 1
 5:     return counter
 6:   }
 7:   return myFunction
 8: }
 9: const increment = createCounter()
10: const c1 = increment()
11: const c2 = increment()
12: const c3 = increment()
13: console.log('example increment', c1, c2, c3)
  1. 1-8行。我们在全局执行上下文中创建了一个新的变量createCounter,并赋值了一个的函数定义。

  2. 9行。我们在全局执行上下文中声明了一个名为increment的新变量。

  3. 9行。我们需要调用createCounter函数并将其返回值赋给increment变量。

  4. 1-8行。调用函数,创建新的本地执行上下文。

  5. 2行。在本地执行上下文中,声明一个名为counter的新变量并赋值为 0

  6. 3-6行。声明一个名为myFunction的新变量,变量在本地执行上下文中声明,变量的内容是另一个函数定义。如第4行和第5行所定义,现在我们还创建了一个闭包,并将其作为函数定义的一部分。闭包包含作用域中的变量,在本例中是变量counter(值为0)。

  7. 7行。返回myFunction变量的内容,删除本地执行上下文。myFunctioncounter不再存在。控制权交给了调用上下文,我们返回函数定义和它的闭包,闭包中包含了创建它时在作用域内的变量。

  8. 9行。在调用上下文(全局执行上下文)中,createCounter返回的值被指定为increment,变量increment现在包含一个函数定义(和闭包),由createCounter返回的函数定义,它不再标记为myFunction,但它的定义是相同的,在全局上下文中,称为increment

  9. 10行。声明一个新变量c1

  10. 继续第10行。查找变量increment,它是一个函数,调用它。它包含前面返回的函数定义,如第4-5行所定义的。(它还有一个带有变量的闭包)。

  11. 创建一个新的执行上下文,没有参数,开始执行函数。

  12. 4行。counter = counter + 1,寻找变量 counter,在查找本地或全局执行上下文之前,让我们检查一下闭包,瞧,闭包包含一个名为counter的变量,其值为0。在第4行表达式之后,它的值被设置为1。它再次被储存在闭包里,闭包现在包含值为1的变量 counter

  13. 5行。我们返回counter的值,销毁本地执行上下文。

  14. 回到第10行。返回值1被赋给变量c1

  15. 11行。我们重复步骤10-14。这一次,在闭包中此时变量counter的值是1。它在第12行设置的,它的值被递增并以2的形式存储在递增函数的闭包中,c2被赋值为2

  16. 12行。重复步骤10-14行,c3被赋值为3。

  17. 第13行。我们打印变量c1 c2c3的值。

你可能会问,是否有任何函数具有闭包,甚至是在全局范围内创建的函数?答案是肯定的。在全局作用域中创建的函数创建闭包,但是由于这些函数是在全局作用域中创建的,所以它们可以访问全局作用域中的所有变量,闭包的概念并不重要。

当函数返回函数时,闭包的概念就变得更加重要了。返回的函数可以访问不属于全局作用域的变量,但它们仅存在于其闭包中。

当一个函数被创建并传递或从另一个函数返回时,它会携带一个背包。背包中是函数声明时作用域内的所有变量。

闭包的不同理解

本质就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。

闭包的优点

优点是私有化数据,在私有化数据的基础上保持数据,

闭包的缺点

内部的变量不会被自动回收掉,使用过多,容易内存溢出

缺点使用不恰当会导致内存泄漏,在不需要用到的时候及时把变量置为null

闭包的应用是非常广泛的,比方我们常见的节流,防抖,

面试回答

**(1)什么是闭包: **

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

优点是私有化数据,在私有化数据的基础上保持数据,缺点使用不恰当会导致内存泄漏,在不需要用到的时候及时把变量置为null

闭包的应用是非常广泛的,比方我们常见的节流,防抖

所蕴含的知识点

  • 作用域&作用域链
  • 执行上下文
  • 缓存,内存
  • 垃圾回收机制
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值