使用嵌套函数返回的简单闭包与闭包

var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; var digit_name = function(n){ return names[n]; } //Execute digit_name(0) 

  var digit_name = (function() { var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; return function(n) { return names[n]; } })(); 

然后像这样执行:

 digit_name(2) 

我知道这些都是闭包,但我也认为两者的设置方式存在一些根本区别。 有人可以指出这两种设置有多么不同(特别是考虑到两者都完成相同的工作)? 将全局变量附加到’window’与嵌套函数以模拟私有变量是我能想到的。

编辑 – 我现在很困惑是否将第一个设置视为关闭…使用chrome,我调查了两个设置..

 var digit_name = (function() { var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; return function(n) { return names[n]; } })(); undefined console.dir(digit_name) function anonymous(n) arguments: null caller: null length: 1 name: ""prototype: Object __proto__: function()  Closure names: Array[9] With Block: CommandLineAPI Global: Window 

但是对于chrome的第一个function,

 var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; var digit_name = function(n){ return names[n]; } undefined console.dir(digit_name) function digit_name(n) arguments: null caller: null length: 1 name: "" prototype: digit_name __proto__: function()  With Block: CommandLineAPI Global: Window 

您可以看到Chrome明确指出第一次设置是否存在关闭,但第二次设置没有。

我知道这些都是封闭的

正确。

但我也认为两者的设置方式存在一些根本区别。

错误。

这个:

 var names = ["zero", "one", "two"]; // outer scope variable var digit_name = function (n) { // closure -------+ return names[n]; // outer scope variable reference | } // ---------------+ 

还有这个

 var digit_name = (function() { // closure --------+ var names = ["zero", "one", "two"]; // outer scope variable | return function(n) { // closure ---+ | return names[n]; // outer scope variable reference | | } // -----------+ | })(); // ----------------+ 

在function上是完全相同的,唯一真正的区别是闭包的数量。

JavaScript中的每个function都会创建一个闭包,就这么简单。

不要让设置闭包的不同方式(函数语句,函数表达式或立即执行的函数表达式)让您感到困惑,最终它们都是相同的。

首先让我们用简单的词语来理解闭包。

Closure是一个内部函数,可以访问外部函数的变量(包装函数)。

现在,闭包函数具有访问具有三个不同范围的变量的神奇力量。

  1. 它的变量是局部范围。
  2. 它的外部函数范围的变量。
  3. 全球范围的变量。

现在,如果我们查看您描述的两种情景。

第一:

 var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; var digit_name = function(n){ return names[n]; } //Execute digit_name(0) 

这里变量namesdigit_name有一个全局范围,因为它是直接声明的,在浏览器的情况下是window (即你可以使用window.names访问它)。 现在,存储在digit_name的函数显然正在访问全局变量。

所以这里closure没有图片。 (这是访问全局变量的函数的一个简单示例。

第二:

  var digit_name = (function() { var names = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight"]; return function(n) { return names[n]; } })(); 

这里digit_name有一个全局作用域,而且存储在digit_name的函数是一个closure ,因为它被包装在一个外部函数( anonymous )中,该函数在声明后立即被调用。 现在变量names具有局部范围,因为它在函数内声明,而closure函数正在访问该函数的局部变量,因为它属于外(包装)函数的范围。

这是闭包function的一个例子。

我希望这有助于你了解closure

有关更多信息,您可以在此处查看更多示例

为了理解范围,您可以参考这个答案