JavaScript中“闭包”到底指的是什么?


71

我了解闭包是什么,但在准确地理解术语closure所指的含义时遇到了一些麻烦。我已经在许多网站中看到过该术语,但很少有人同意该术语的实际定义。

  • 是保留在堆栈框架中的变量吗?
  • 是要返回的函数吗?
  • 它是外部功能的范围吗?
  • 它是内部(返回的)函数的范围吗?
  • 返回函数后,可能是将变量保留在堆栈框架中的概念吗?

有人可以准确地告诉我closure指的是什么吗?


8
+1是因为您会问一些方便的问题
亚历克斯

在查看了1/2打的解释之后..这个看起来很适合分解主要考虑因素sitepoint.com/javascript-closures-demystified
Gene Bo

Answers:


45

来自JavaScript闭包

两个单句摘要:

闭包是函数的局部变量-在函数返回后保持活动状态,或者

关闭是一个堆栈框架,当函数返回时,该框架不会被释放。(就像“堆栈框架”被分配了,而不是放在堆栈上一样!)

一篇关于闭包的非常好的文章

JavaScript闭包

“闭包”是一个表达式(通常是一个函数),可以将自由变量与绑定这些变量的环境(“封闭”表达式)一起使用。

闭包的简单解释是ECMAScript允许内部函数;其他函数的函数体内的函数定义和函数表达式。并且允许那些内部函数访问其外部函数中的所有局部变量,参数和已声明的内部函数。当使那些内部函数之一可以在其中包含该函数的外部访问时,形成一个闭包,以便可以在外部函数返回后执行它。此时,它仍然可以访问其外部函数的局部变量,参数和内部函数声明。这些局部变量

这里的一个很好的例子

JavaScript,该关闭了


我已经用图形解释写了一系列文章。在此处阅读第4章和第5章:rahuldotout.wordpress.com/2011/05/15/…– rahulmohan 2011
6

A closure is the local variables for a function - kept alive after the function has returned, or它应该只可变吗?或功能?或两者?因为在正式文件上他们说内部功能是闭包。developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
Asif Mushtaq,

6

它是一个“持有”另一个范围内的一个或多个引用的函数。例如:

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。

这是图形说明。


4

对我来说,JS中的闭包允许您执行以下操作。
尽管在外部函数中声明了“ a”,但将其添加到“ b”中后,它仍在内部函数中可用。

function adder(a){
  return function(b){
    return a + b;
  };
}
var add5 = adder(5);
alert( add5(10) );

对于极端的JS闭包用法,您可以看一下PURE库的源代码(一个JS模板引擎)


2
我知道闭包的含义是什么,但是您的回答仍然无法真正改善closure真正的含义
Andreas Grech 2009年

我喜欢这个示例,因为它是我所知道的较小的示例,它显示了什么是闭包,并且在我学习函数式JS时对我来说最有意义。
麦克风

您是否从Stoyan Stefanov的JavaScript Patterns书中获得了此示例?
丹·束

@丹,没有。为什么?完全一样吗?
麦克风

2
我看到了第83页...的确相似。但是这本书是在回答这个问题之后将近一年印出的;)
麦克风

2

据我所知,闭包是在另一个函数中定义的一个函数,该函数超出了父函数的作用域。一个常见的例子是回调:

function delay_message(msg)
{
     setTimeout(function closure() { alert(msg); }, 1000);
}

在这种情况下,以上代码function closure在的主体内定义delay_message,但函数定义-以及父函数的变量msg-超出了delay_message函数调用的范围。


所以您是说闭包<i>是</ i>内部函数?
Andreas Grech

“关闭”是功能及其状态的组合。即,内部函数绑定到来自外部函数的一组局部变量。
intgr

内部函数(function closure)是在解析时创建的,但此时没有关闭。在function delay_message执行时创建一个闭包,并将其状态绑定到function closure
intgr

匿名函数不是闭包。请不要继续传播这种误称。
Mike Axiak 2010年

2

考虑下面的代码,它使用变量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进行操作的任何函数



1

闭包是从嵌套函数声明或函数表达式(即lambda表达式)创建的函数值,其主体包含一个或多个对在外部(而非全局)范围内声明的变量的引用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.