对闭包的理解(closure)

时间:2021-06-09 03:15:28

什么是闭包(closure):

当你声明一个局部变量时,这个局部变量有作用域,通常局部变量值只存在于你定义的Block or Function中:

function() {
var a = 1;
console.log(a); // works
}
console.log(a); // fails

如果你想要尝试访问一个局部变量,大多数的语言都会在当前作用域去找,然后去找上一层的作用域,最后找到根作用域(root scope)

var a = 1;
function() {
console.log(a); // works
}
console.log(a); // works

当一个Block or Function工作完后,我们就不需要它的局部变量了,所以我们就把它丢出内存了

这是我们普遍希望这样做的

闭包就是永久存在的局部变量

举个例子吧:

outer = function() {
var a = 1;
var inner = function() {
console.log(a);
}
return inner; // this returns a function
} var fnc = outer(); // execute outer to get inner
fnc();

这里我定义了一个函数内的函数。内部函数可以访问所有外部函数的局部变量,包括a。该变量a在内部函数的范围内。

通常,当一个函数退出时,它的所有局部变量都会被消灭。但是,如果我们返回内部函数并将其分配给一个变量fnc,以便它在outer退出后保持不变,那么inner定义范围内的所有变量也会保留。该变量a已被关闭 - 它在闭包内。

请注意,该变量a是完全私有的fnc。这是一种使用JavaScript等函数式编程语言创建私有变量的方法。

正如您可能会猜到的那样,当我使用fnc()它会打印出a“1”的值。

在没有闭包的语言中,a当函数outer退出时,变量将被垃圾收集并抛弃。调用fnc会引发错误,因为a不再存在。

在JavaScript中,变量a持续存在,因为变量作用域是在函数首次声明时创建的,只要函数继续存在,该变量就一直存在。

a属于作用域outer。作用域inner有一个指向范围的父指针outerfnc是一个指向的变量innera只要fnc持续存在,就会持续存在。a在闭包之内。

这里我定义了一个函数内的函数。内部函数可以访问所有外部函数的局部变量,包括a。该变量a在内部函数的范围内。

通常,当一个函数退出时,它的所有局部变量都会被吹走。但是,如果我们返回内部函数并将其分配给一个变量fnc,以便它在outer退出后保持不变,那么inner定义范围内的所有变量也会保留。该变量a已被关闭 - 它在闭包内。

所以闭包总结为:

如果在一个内部函数里,对外部作用域(但不是在全局作用域的变量)进行引用,那么内部函数就会被认为是闭包。