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

时间:2016-01-05 15:50:28

标签: javascript jquery closures

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

digit_name(0)

VERSUS

 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()
 <function scope>
     Closure names: Array[9]
     With Block: CommandLineAPI
     Global: Window

然而,对于chrome中的第一个函数,

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()
<function scope>
     With Block: CommandLineAPI
     Global: Window

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

2 个答案:

答案 0 :(得分:1)

  

我知道这些都是封闭

正确。

  

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

错误。

此:

touch test2.txt
grep -o '".*"' test.txt | sed s/"_"/" "/g > test2.txt
rm test.txt
rename s/"test2"/"test"/ test2.txt

和这个

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

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

JavaScript中的每个var digit_name = (function() { // closure --------+ var names = ["zero", "one", "two"]; // outer scope variable | return function(n) { // closure ---+ | return names[n]; // outer scope variable reference | | } // -----------+ | })(); // ----------------+ 都会创建一个闭包,就这么简单。

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

答案 1 :(得分:0)

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

  

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

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

  
      
  1. 它的局部范围的变量。
  2.   
  3. 它的外部功能范围的变量。
  4.   
  5. 全球范围的变量。
  6.   

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

第一:

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访问它1}})。现在,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函数正在访问此函数的局部变量,因为它属于外(包装)函数的范围。

  

这是闭包功能的一个例子。

我希望这可以帮助您理解closure

有关详细信息,您可以查看更多示例here

为了理解范围,您可以参考this回答