Understanding closure in Javascript

后端 未结 8 660
不思量自难忘°
不思量自难忘° 2020-12-28 23:19

I\'m trying to wrap my head around closures in Javascript.

Here is an example from a tutorial:

function greeter(name, age) {
  var message = name + \         


        
相关标签:
8条回答
  • 2020-12-28 23:58

    I don't think this is a good example for private variables, because there are no real variables. The closure part is that the function greet can see message (which is not visible to the outside, hence private), but it (or anyone else) is not changing it, so it is more of a constant.

    How about the following example instead?

    function make_counter(){
        var i =0;
        return function(){
            return ++i;
        }
    }
    
    var a = make_counter();
    console.log(a());  // 1
    console.log(a());  // 2
    var b = make_counter();
    console.log(b());  // 1
    console.log(a());  // 3
    
    0 讨论(0)
  • 2020-12-29 00:01

    The purpose of a closure is so that the variables you use inside a given function are guaranteed to be "closed" which means they do not depend on external variables - they only depend on and use their arguments. This makes your Javascript methods closer to a pure function, that is, one that returns the same value for the same given arguments.

    Without using closures, your functions will be like Swiss cheese, they will have holes in them. A closure plugs up those holes so the method doesn't depend on variables higher in the scope chain.

    Now, up until this point, my answer has been simply about organizing your code and style. So take this simple example. At the line with the comment, I invoke a function and the value of the variable a is captured for future use.

    var a = "before";
    var f = function(value) {
        return function()
        {
          alert(value);
        }
    } (a); //here I am creating a closure, which makes my inner function no longer depend on this global variable
    a = "after";
    
    f(); //prints "before"
    

    Now, why would you need to do this? Well, here's a practical example. Consider the following code that uses jQuery to add 5 links to the document. When you click a link, you would expect it to alert the number associated with the link, so clicking the first you would think would alert 0, and so on. But, this is not the case, each link will alert the value of 5. This is because the function I define depends on the variable i which is being modified outside the context of the function. The function I pass into bind is a Swiss cheese function.

    for (var i = 0; i < 5; i++)
    {
        var a = $('<a>test link</a>').bind('click', function(){
            alert(i);
        });
        $(a).appendTo('body');
    }
    

    Now, let's fix this by creating a closure so each link will alert its correct number.

    for (var i = 0; i < 5; i++)
    {
        var fn = function (value) {
            return function() {
                alert(value);
            };
        } (i); //boom, closure
        var a = $('<a>test link</a>').bind('click', fn);
        $(a).appendTo('body');
    }
    
    0 讨论(0)
提交回复
热议问题