传说中面试必考的闭包概念,我来啦~
1、闭包,closure,是指函数本身和该函数声明时所处的环境状态的组合。
要理解这个加粗的字“该函数声明时”,我个人jio得闭包概念讲的最明白的是《JavaScript权威指南》最新版原书第七版,让我来引用一下。
JavaScript使用词法作用域。
这意味着函数执行时使用的是定义函数时生效的变量作用域,而不是调用函数时生效的变量作用域,为了实现词法作用域,JavaScript函数对象的内部状态不仅要包括函数代码,还要包括对函数定义所在作用域的引用。
这种函数对象与作用域(即一组变量绑定)组合起来解析函数变量的机制,在计算机科学文献中被称作闭包(closure)。
就是说函数能够“记忆”其定义时所处的环境。即使函数不在其定义的环境中被调用,也能访问定义时所处环境的变量。
2、来举个面试题的栗子理解一下
作用域应用的特殊情况,有两种表现:
函数作为参数被传递
函数作为返回值被返回
(1)函数作为参数被传递
// 函数作为返回值 function create() { const a = 100; return function () { console.log(a); } } const fn = create(); const a = 200; fn();// 100
这里输出的就是100,而不是200
(2)函数作为返回值被返回
// 函数作为参数 function print(fn) { let b = 100; fn(); } let b = 200; function fn() { console.log(b); } print(fn);// 200
这里输出的是200,而不是100
所以,一定要理解刚才第一点说的,变量到底取什么值,要去函数定义的地方,向上级作用域查找,不是在执行的地方查找!!!
3、来观察一下刚才的闭包
我们在刚才这个小栗子里打个debugger看下
// 函数作为返回值 function create() { debugger const a = 100; return function () { console.log(a); } } const fn = create(); const a = 200; fn();// 100
我们在浏览器里会发现跑着跑着就出现了闭包变量
你看它都有闭包变量了,它还不是闭包?那必须就是闭包。
4、其实所有JavaScript函数都是闭包
《JavaScript权威指南》
严格来说,所有JavaScript函数都是闭包。但由于多数函数调用与函数定义都在同一个作用域内,所以闭包的存在无关紧要。闭包真正值得关注的时候,是定义函数与调用函数的作用域不同的时候。最常见的一个情形就是一个函数返回了在它内部定义的嵌套函数。
5、闭包的其他理解
不会还有人不理解闭包吧~
闭包并不是JavaScript里面才有的概念,有很多定义,我都打出来看看