美文网首页我爱编程
探索奥秘~闭包

探索奥秘~闭包

作者: 小鱼儿_逆流而上 | 来源:发表于2018-04-12 00:14 被阅读0次

在我学习初期我对闭包的理解也不是很深,最近在学习了js更深入的知识后,对闭包有了更加深入的了解,下面我就跟大家详细解读一“闭包”!

一、首先什么是闭包?

“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
当一个函数能够记住并访问到其所在的词法作用域及作用域链,特别强调是在其定义的作用域外进行的访问,此时该函数和其上层执行上下文共同构成闭包。

相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:

function a(){
 var i=0;
 function b(){
 alert(++i);
 }
 return b;
}
var c = a();
c();

这段代码有两个特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

**需要明确的几点:
1、闭包一定是函数对象(wintercn大大的闭包考证)
2、闭包和词法作用域,作用域链,垃圾回收机制息息相关
3、当函数一定是在其定义的作用域外进行的访问时,才产生闭包
4、闭包是由该函数和其上层执行上下文共同构成

二、接下来我们来看下闭包是如何产生的?
现在我假设JS引擎执行到这行代码
let baz = foo();
此时,JS的作用域气泡是这样的:


38412730-97a3fd6e-39bc-11e8-9a53-208d71ca98eb-660x572.png

这个时候foo函数已经执行完,JS的垃圾回收机制应该会自动将其标记为”离开环境”,等待回收机制下次执行,将其内存进行释放(标记清除)。
但是,我们仔细看图中粉色的箭头,我们将bar的引用指向baz,正是这种引用赋值,阻止了垃圾回收机制将foo进行回收,从而导致bar的整条作用域链都被保存下来。
接下来,baz()执行,bar进入执行栈,闭包(foo)形成,此时bar中依旧可以访问到其父作用域气泡中的变量a。

我们借助chrome的调试工具看下闭包产生的过程:
当JS引擎执行到这行代码let baz = foo();时:


38487982-9301fd1a-3c14-11e8-8238-57321d84eb05-660x439.jpg

图中所示,let baz = foo();已经执行完,即将执行baz();,此时Call Stack中只有全局上下文。
接下来baz();执行:


38488086-e0d4349a-3c14-11e8-84af-ea05e7546a43-660x439.jpg
我们可以看到,此时bar进入Call Stack中,并且Closure(foo)形成。
三、闭包的应用场景
1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。

2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
以上两点是闭包最基本的应用场景,很多经典案例都源于此!

闭包的奥妙
闭包,它并不是很神秘,反而是在我们的程序中随处可见,让我们静下心来,品味闭包的味道,走进“闭包”世界,感受它的魅力所在!

相关文章

  • 探索奥秘~闭包

    在我学习初期我对闭包的理解也不是很深,最近在学习了js更深入的知识后,对闭包有了更加深入的了解,下面我就跟大家详细...

  • Swift底层探索:闭包

    闭包是可以在你的代码中被传递和引用的功能性独立代码块。闭包在实现上是一个结构体,它存储了一个函数(通常是其入口地址...

  • Swift探索(七): 闭包

    一:函数类型 每个函数都有种特定的函数类型,函数的类型由函数的参数类型和返回类型组成。 上述代码中 (Double...

  • 闭包特性的探索

    闭包体现了JavaScript的一个特性,函数体可以访问定义该函数的作用域的变量,但是定义该函数的作用域不能访问函...

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

  • Python闭包

    闭包 = 环境变量 + 函数 调用闭包内部的环境变量 闭包的经典误区 闭包与非闭包实现人类走路 非闭包 闭包

  • 闭包(closure)

    ● 闭包基础 ● 闭包作用 ● 闭包经典例子 ● 闭包应用 ● 闭包缺点 ● 参考资料 1、闭包基础 作用域和作...

网友评论

    本文标题:探索奥秘~闭包

    本文链接:https://www.haomeiwen.com/subject/qhetkftx.html