简体   繁体   中英

Can someone explain how this javascript closure works?

Ok, I am staring to learn how closures work......and I have been stuck on this one for a few hours. I just don't understand how it works.

I have to find the final value for the variable result .

    var hidden = mystery(3);
    var jumble = mystery3(hidden);
    var result = jumble(2);

    function mystery ( input ){
      var secret = 4;
      input+=2;
      function mystery2 ( multiplier ) { 
         multiplier *= input;
         return secret * multiplier;
      }
      return mystery2;
    }


    function mystery3 ( param ){
      function mystery4 ( bonus ){
        return param(6) + bonus;
      }
      return mystery4;
    }

The answer is 122, but I am not sure how that number.

The answer that I calculated is is 362. That was obviously wrong.

I got 362 like this

var hidden = mystery(3);
var jumble = mystery3(hidden);
var result = jumble(2);

function mystery ( input ){  //used 3 as an input
  var secret = 4;
  input+=2;
  function mystery2 ( multiplier ) { //used 3 as multiplier
     multiplier *= input; // 3 * 5
     return secret * multiplier;
  }
  return mystery2;   //returned 60
}


function mystery3 ( param ){  //used 60 as param
  function mystery4 ( bonus ){ //used 2 as bonus
    return param(6) + bonus; //60(6) + 2
  }
  return mystery4; // answer is 362
}

Can someone tell me how exactly you can get the answer 122?

In simple words, closure means that a value of a local variable that has gone out of scope is retained inside a function.

Let's look at your code step by step:

var hidden = mystery(3);

Now, mystery returns a function. But what does it actually return. A simple alert(hidden) statement will tell you that it returns,

function mystery2( multiplier ) {
    multiplier *= input;
    return secret * multiplier;
}

Now if you look at the values of the local variables of this function,

  • multiplier is an argument, it's value will be whatever that is passed to it when it is called
  • But what is the value of input ?
  • And of secret ?

This is where closures come into play. The value of input will be taken from the scope that this function was created on. What was the values for input and secret when this function was created? Let's take a look at mystery again:

function mystery ( input ){ // value 3 is passed here as a parameter
    var secret = 4;
    input+=2;
    ...
}

So we find that input was in fact had the value 5 , and secret had the value 4 . Now the returned function essentially becomes equivalent to:

function mystery2( multiplier ) {
    multiplier *= 5;
    return 4 * multiplier;
    // for future use, let's say that above statement is equivalent to:
    // return 4 * (multiplier * 5);                               ----- (1)
    // (now be a good boy/girl and don't scroll down to end)
}

OK, next:

var jumble = mystery3(hidden);

Again, mystery3 returns a function. alert(jumble) gives us this:

function mystery4( bonus ){
    return param(6) + bonus;
}

Again, thinking in the same way as before we can say that this is equivalent to:

function mystery4( bonus ){
    return mystery2(6) + bonus; // param <- hidden <- mistery2
} //                                                             ----- (2)

And lastly,

var result = jumble(2);

Which is equivalent to:

var result = mystery4(2);

That is,

var result = mystery2(6) + 2; // because (2), see above

Which is,

var result = 4 * (6 * 5) + 2; // because (1), see above

Phew...

122

I've changed some names around to make it more readable for me, add a few comments to point out values at the time of the line's execution.

var mystery2_handle = mystery(3);
var mystery4_handle = mystery3(mystery2_handle);
var result = mystery4_handle(2);

function mystery ( input ){
    var secret = 4;
    input+=2; //5
    function mystery2 ( multiplier ) { 
        multiplier *= input; //6*5
        return secret * multiplier; //30*4
    }
    return mystery2;
}


function mystery3 ( _mystery2_handle ){
    function mystery4 ( bonus ){ //2
        return _mystery2_handle(6) + bonus; //120+2
    }
    return mystery4;
}

Let's go step by step:

  1. mystery(3) -> input will be set to 5
  2. then return mystery2 function handle
  3. pass that handle to mystery3
  4. which returns mystery4 handle inside of which the mystery2 handle is accessed
  5. execute mystery4 with bonus parameter set to 2
  6. execute mystery2 with multiplier parameter set to 6
  7. in which multiplies it by 5 = 30
  8. then multiply secret 4 by 30 = 120
  9. return the 120 to which 2 (bonus) is added in mystery 4
  10. Voila 122

http://jsfiddle.net/3F4pz/ Run the code insert alerts where needed to check data. Just remember that even though the code is top down does not mean it's executed that way. And I'm not sure how you came up with 362.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM