simple closure vs closure with nested function return

China☆狼群 提交于 2019-12-23 02:39:27

问题


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];
    }
})();

then execute it like this:

digit_name(2)

I know these are both closures, but I also think that there are some fundamental differences between the way the two are setup. Can someone point out how different are these two setups (especially considering both get the same job done)? Attaching a global variable to the 'window' vs nesting functions to emulate private variable is one I can think of..

EDIT - I am now confused whether to think of the first setup as a closure or not...Using chrome, I investigated the two setups..

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

However for the first function in 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

You can see that Chrome explicitly indicates the existence of closure for the first setup, but not for the second setup..


回答1:


I know these are both closures

Correct.

but I also think that there are some fundamental differences between the way the two are setup.

Wrong.

This:

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

and this

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

is exactly the same thing, functionally, the only real difference being the number of closures.

Every function in JavaScript creates a closure, it's as simple as that.

Don't let the different ways of setting up closures (function statements, function expressions or immediately-executed function expressions) confuse you, ultimately it all amounts to the same thing.




回答2:


First let us understand what closure is in simple words.

Closure is a inner function which has access to variables of the outer function (wrapper function).

Now the closure function has magical power of accessing variables with three different scopes.

  1. Variables of it's local scope.
  2. Variables of it's outer function's scope.
  3. Variables of global scope.

Now if we look at your both the scenarios you described.

First :

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

digit_name(0)

here the variable names and digit_name has a global scope as it is declared directly, in browser's case which is window ( i.e you can access it using window.names). Now the function stored in digit_name is clearly accessing a global variable.

So here closure no where comes in picture. (It's a simple example of function accessing a global variable.

Second :

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

Here digit_name has a global scope and the function stored in digit_name is a closure, because it is wrapped up in an outer function (anonymous) which is immediately called after declaration. Now the variable names has a local scope because it is declared inside a function and the closure function is accessing a local variable of this function because it falls under the scope of outer (wrapper) function.

This is an example of closure function.

I hope this helps you to understand closure.

For more information you can take a look at more examples here

and for understanding scope you can refer this answer



来源:https://stackoverflow.com/questions/34615754/simple-closure-vs-closure-with-nested-function-return

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!