如何理解js闭包

要理解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变量的内容,删除本地执行上下文。myFunction和counter不再存在。控制权交给了调用上下文,我们返回函数定义和它的闭包,闭包中包含了创建它时在作用域内的变量。
  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 c2和c3的值为1,2,3。
    我的理解:父函数A中声明变量i和子函数a,a函数调用A函数中的变量i,父函数return出子函数a。当把父函数的执行结果赋值给其他变量b时,会执行A,得到结果为返回的子函数a。
    当调用b函数执行时,A已经被销毁,i和a也被销毁。但是此时b会从闭包中找到变量i并执行。这就是完整的闭包过程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值