(JS)闭包是否需要函数内部的函数

mac*_*ost 8 javascript closures

我对封闭的固有概念有点困难.我得到了基本的想法,但事情就是这样:我认为,从技术上讲,每个Javascript函数中都有"闭包".引用维基百科:

在计算机科学中,闭包(也是词法闭包,函数闭包或函数值)是一个函数以及该函数的非局部名称(自由变量)的引用环境.据说这种功能是"封闭"其自由变量.

因此,既然您可以在函数内部定义变量,那么它们将"关闭"到代码的其余部分,因此我将其视为闭包.因此,据我所知:

(function(){var a = 1;}())
Run Code Online (Sandbox Code Playgroud)

是一个(不是非常有用)闭包的例子.或者哎呀,即使只是这样:

function(){var a = 1;}
Run Code Online (Sandbox Code Playgroud)

但是,我认为我的理解可能是错误的.其他人告诉我,对于一个关闭它必须坚持一个状态,所以因为没有任何东西超出该代码,它不是真正的闭包.这表明你需要:

function(foo){foo.a = 1;}(bar); // bar.a = 1
Run Code Online (Sandbox Code Playgroud)

甚至(以确保不可修改):

function(foo){var a = 1; bar.baz = function() { return a}}(bar); // bar.baz() = 1
Run Code Online (Sandbox Code Playgroud)

因此,从技术上讲(我知道几个例子实际上毫无意义,但是)上述哪些例子实际上是闭包的例子.并且闭包只需要是一个空间(即在JS函数内),其中可以存储无法从外部访问的变量,或者持久性是闭包定义的关键部分吗?

编辑

刚刚注意到Stack Overflow上"closures"标签的维基定义:

闭包是一个第一类函数,它引用(关闭)变量来自定义它的作用域.如果闭包在其定义范围结束后仍然存在,则它关闭的变量也将继续存在.

虽然SO维基当然不是最终权威,但第一句似乎与我对该术语的理解相关.第二句则意味着封闭如何被使用,但它并没有看起来像一个要求.

编辑#2

如果从这里的变化答案,维基百科答案和标签答案中不清楚,似乎没有就"封闭"这个词甚至意味着什么达成明确的共识.所以虽然我很欣赏到目前为止的所有答案,但如果你按照作者对闭包的定义来说它们都是有意义的,我猜我真正想要的是......是否有任何实际的"权威"定义(如果是这样,它如何适用于以上所有)?

Hen*_*olm 9

你被"封闭"这个词的来源错误地假设误入歧途.

在语言论的背景下,封闭的一点是,该功能可以参考声明的变量自己的定义.它是否具有内部变量,或者内部变量是否从外部不可见是无关紧要的.换句话说,它是关于看见从功能到其定义的环境,不是看距离之外的功能.

为什么这个奇怪的词呢?看看上一个例子中的函数:

bar.baz = function() { return a }
Run Code Online (Sandbox Code Playgroud)

此函数包含a对函数体本身未定义的变量的提及.它是函数体的"自由"变量,在定义中是一个"洞".如果不通过一些无关的方法知道a正文中的标识符所指的变量,我们就无法执行该函数.在运行时形成一个闭包,将这个"开放"函数体与对应的变量相对应,从而关闭定义中的孔.这就是名字的来源.

(如果你想要完全技术性的解释,那么潜在的概念就是lambda-calculus中的一个"封闭"术语,这意味着没有自由变量.只有封闭术语具有独立的含义.闭包是一个闭包. (通常编译的)非封闭的源代码片段,以及使其行为类似于封闭术语的上下文信息,因此可执行).

附录:常用的成语

function() {
   var blah;
   // some code here
}();
Run Code Online (Sandbox Code Playgroud)

关键是不要得到一个闭包(当然,你会得到一个,但它不会对你做任何有趣的事情),而是为变量创建一个局部范围blah.本地范围在概念上与闭包完全不同 - 实际上除了Javascript之外的大多数C-lookalike都会在每个{}块中创建它们,而它们可能会或可能根本没有闭包.