我明白闭包是什么,但我在理解这个术语closure
所指的内容时遇到了一些麻烦。我在许多网站上看到过这个术语,但他们很少就它的实际定义达成一致。
- 是保存在堆栈帧上的变量吗?
- 是返回的函数吗?
- 是外层函数的作用域吗?
- 它是内部(返回)函数的范围吗?
- 是否可能是在返回函数后将变量保留在堆栈帧上的概念?
有人能准确地告诉我closure
指的是什么吗?
我明白闭包是什么,但我在理解这个术语closure
所指的内容时遇到了一些麻烦。我在许多网站上看到过这个术语,但他们很少就它的实际定义达成一致。
有人能准确地告诉我closure
指的是什么吗?
两个一句话总结:
闭包是函数的局部变量 - 在函数返回后保持活动状态,或者
闭包是一个堆栈帧,当函数返回时它不会被释放。(好像一个“堆栈帧”被 malloc 分配而不是在堆栈上!)
一篇关于闭包的好文章
“闭包”是一个表达式(通常是一个函数),它可以具有自由变量以及绑定这些变量(“关闭”表达式)的环境。
闭包的简单解释是 ECMAScript 允许内部函数;其他函数的函数体内的函数定义和函数表达式。并且允许这些内部函数访问其外部函数中的所有局部变量、参数和声明的内部函数。当这些内部函数之一在包含它的函数之外可以访问时,就会形成一个闭包,以便它可以在外部函数返回后执行。此时它仍然可以访问其外部函数的局部变量、参数和内部函数声明。那些局部变量,
一个很好的例子在这里
它是一个“持有”一个或多个对另一个范围内某物的引用的函数。例如:
var myArrayOfFunctions = [];
for(var i = 0; i<3: i++)
{
//Note how the function being defined uses i,
//where i lives in the parent's scope, this creates a closure
myArrayOfFunctions[i] = function(a) { return a + i;}
}
myArrayOfFunctions[0](5); //Prints 8 WTF!
myArrayOfFunctions[1](5); //8 again
myArrayOfFunctions[2](5); //Well, this 8 was expected
发生这种情况是因为当函数被“创建”时,它们不复制 i 的值,它们持有对 i 的引用,所以当我们调用函数时,它们使用 i 的当前值,即 3。
对我来说,JS 中的闭包允许您执行以下操作。
“a”在添加到“b”时在内部函数中仍然可用,尽管它是在外部声明的。
function adder(a){
return function(b){
return a + b;
};
}
var add5 = adder(5);
alert( add5(10) );
对于 JS 闭包的极端用法,您可以查看PURE 库(一个 JS 模板引擎)的源代码
据我所知,闭包是在另一个函数中定义的函数,它的生命周期超过父函数的作用域。一个常见的例子是回调:
function delay_message(msg)
{
setTimeout(function closure() { alert(msg); }, 1000);
}
在这种情况下,上面的内容function closure
是在 的主体内定义的delay_message
,但是函数定义——以及父函数的变量msg
——比delay_message
函数调用的范围长。
考虑以下使用变量 a 和 b 创建闭包的代码
closure=(function(){
var a=3
var b=5
return function(operation){
return operation(a,b)
}
}())
// The variables a and b are now part of the closure (They are retained even after the outer function returns)
closure(function(x,y){return x+y}) // outputs 8
closure(function(x,y){return x*y}) // outputs 15`
这个特殊的闭包现在可以接受任何对变量 a 和 b 进行操作的函数