定义

当一个函数访问了函数外定义的变量(对于该函数来说,是一个自由变量;函数内定义的变量叫做约束变量),就形成了一个广义上的闭包。

而 js 中的闭包,一般是指在函数外访问到了函数内部作用域的变量,那么这种情况就叫做闭包(实际上更像是闭包的一种应用)

产生条件

在 js 中,如果要产生闭包,需要 1 个条件:

当前作用域存在指向父作用域的引用

理解为:上级作用域变量的生命周期,因为被下级作用域引用时,而没有被释放。导致上级作用域内变量,等到下级作用域执行完成后才得到正常的释放。

例子

1
2
3
4
5
6
7
8
9
10
11
function outer() {
var a = 1;
return function inner() {
a = a + 1;
console.log("a=", a);
};
}
let A = outer();
A(); // a= 2
A(); // a= 3
A(); // a= 4

当 outer 执行后,outer 函数内部的变量应该全部被销毁。但是因为 outer 返回了一个内部函数,而该内部函数引用了父作用域中的一个变量,因此当该函数被返回时,该函数执行时的作用域也被拷贝了一份存入内存中。使得执行函数 A 时,能通过内部函数 inner 访问到 outer 函数内部的变量 a。

一个比喻

通俗地讲就是别人家有某个东西,你想拿到但是因为权限不够(不打死你才怪),但是你可以跟家里的孩子套近乎,通过他拿到!
这个家就是局部作用域,外部无法访问内部变量,孩子是返回对象,对家里的东西有访问权限,借助返回对象间接访问内部变量!

参考:

闭包的解释