JavaScript闭包

2020-01-01  本文已影响0人  agamgn

前言

在面试过程中,闭包是常考的问题,在很多框架和库中也使用到了闭包,包括我们在平时写代码也或多或少使用到了闭包。

一、什么是闭包

闭包的概念描述很多,我比较认同《你不知道的JavaScript》这样描述:

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

在正式理解闭包之前,我们需要清楚什么是作用域词法作用域内存回收机制

1.1、作用域

一言以蔽之,作用域就是一套规则,用于确定在何处以及如何查找变量(标识符)的规则,形象描述的话,可以认为它是一个封闭的空间,只允许在这个封闭的空间内进行一些操作,也将这个封闭空间称为私有作用域。
更多的参考本篇作用域以及作用域链

1.2、内存回收机制

内存回收机制就是不在用到的内存,我们系统就自动进行回收从而清理出空间供其他程序使用
更多的参考本篇JavaScript内存管理

二、讲解闭包

上面已经提到了闭包的概念,这里直接看一段代码:


闭包demo.png

这里可以很清晰的展示闭包:

三、再看一个例子

闭包demo3.png

我们的预期结果是1~10,但是确输出10次11。这是因为setTimeout中的匿名函数执行的时候,for循环都已经结束了,for循环结束的条件是i大于10,所以当然是输出10次11。
究其原因:i是声明在全局作用中的,定时器中的匿名函数也是执行在全局作用域中,那当然是每次都输出11了。
使用闭包解决:我们可以让i在每次迭代的时候,都产生一个私有的作用域,在这个私有的作用域中保存当前i的值。


闭包demo4.png

这样就达到我们的预期了。

四、闭包的应用

4.1、实现私有成员
闭包demo5.png
4.2、保护命名空间,避免污染全局变量
闭包demo6.png
上面这个用法,叫做函数柯里化,就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术
闭包demo7.png
注意事项: 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题

五、总结

理解闭包是迈向高级JS程序员的必经之路,理解了其解释和运行机制才能写出更为安全和优雅的代码。
代码地址

上一篇 下一篇

猜你喜欢

热点阅读