持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
前言
闭包,一个用了这么多年还在慢慢了解的概念。虽然有了大量的JavaScript的使用经验,但是好像又从未真正去理解闭包的概念。
总是感觉闭包是个很隐蔽的东西,它的工作原理也是一个很神奇的东西。
闭包,并不是JavaScript中的一个需要去学习的语法或者模式才能使用的东西,它无处不在,只要你能识别它即可。
识别闭包
😎 当函数可以记住并访问所在的词法作用域时,就会产生闭包,就算函数是在当前词法作用域之外去执行。
function foo(){
var a = 1;
function bar(){
console.log(a);
}
bar();
}
foo();
- 此时在
bar函数中输出的a就会是foo函数中定义的值
😵 上面这段代码展示出来的结果是闭包嘛?是,但也不是
bar函数中对a的引用方法只是词法作用域里面的查找规则,这些规则只是闭包中的一部分而已。bar函数则具有一个涵盖foo函数作用域的闭包,也可以理解为bar函数被封闭在foo函数的作用域里面。
从上面的代码中,我们并不能直接观察闭包是如何工作的,我们只能看出它属于词法作用域,而闭包则隐藏在代码之中而已。
function foo(){
var a = 1;
function bar(){
console.log(a);
}
return bar;
}
var fun = foo();
fun();
🧐 这个输出的 1 就是闭包的效果了。
bar函数的词法作用域能够访问foo函数的内部作用域。- 我们把
bar函数当做一个值去传递,并把bar函数当作返回值。
😕 我们通常对于函数执行的理解中,会觉得 foo函数在执行之后,会把内部作用域都销毁掉,因为引擎的垃圾回收器会用来释放不再使用的内存空间。
由于 foo函数的内容看上去不会再使用了,所以会考虑将其回收掉。
闭包的神奇之处就是可以
阻止回收这件事情的发生。由于bar函数的使用,内部作用域依然会存在,因为不会被回收。
bar函数持有对该作用域的引用,这个引用就被称为
闭包。
总结
通过上面的例子你可能会有点迷糊,可能还需要更多的时间去理解。只要在项目开发过程中,慢慢熟悉闭包的原理,就会发现其实闭包并不复杂,它出现在你的逻辑代码的各个地方。