有人可以解释这个javascript闭包是如何工作的吗?

时间:2014-07-21 02:18:14

标签: javascript closures

好的,我正盯着了解封口是如何工作的......而且我已经被困在这个封闭器上几个小时了。我只是不明白它是如何运作的。

我必须找到变量 结果 的最终值。

    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;
    }

答案是122,但我不确定这个数字是多少。

我计算的答案是362.这显然是错误的。

我这样得了362

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
}

有人能告诉我你究竟能得到答案122吗?

2 个答案:

答案 0 :(得分:2)

简单来说,闭包意味着超出范围的局部变量的值保留在函数内。

让我们一步一步看看你的代码:

var hidden = mystery(3);

现在,mystery返回一个函数。但它实际上又回归了什么呢。一个简单的alert(hidden)语句会告诉你它返回,

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

现在,如果你看一下这个函数的局部变量的值,

  • multiplier是一个参数,它的值将是调用它时传递给它的任何值
  • input的价值是什么?
  • secret

这是闭包发挥作用的地方。输入的值将取自创建此函数的范围。创建此函数时inputsecret的值是多少?让我们再看看mystery

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

因此,我们发现input实际上具有值5secret具有值4。现在返回的函数基本上等同于:

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)
}

好的,接下来:

var jumble = mystery3(hidden);

同样,mystery3返回一个函数。 alert(jumble)给了我们这个:

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

再次,以与以前相同的方式思考,我们可以说这相当于:

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

最后,

var result = jumble(2);

相当于:

var result = mystery4(2);

即,

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

是,

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

...呼

122

答案 1 :(得分:1)

我已更改了一些名称,使其对我来说更具可读性,添加一些注释以指出行执行时的值。

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;
}

让我们一步一步走:

  1. 谜(3) - &gt;输入将设置为5
  2. 然后返回mystery2函数句柄
  3. 将该句柄传递给mystery3
  4. 返回访问mystery2句柄的mystery4句柄
  5. 执行myst​​ery4并将参数设置为2
  6. 执行myst​​ery2,乘数参数设置为6
  7. 其中乘以5 = 30
  8. 然后将秘密4乘以30 = 120
  9. 返回神秘4中添加了2(奖励)的120
  10. Voila 122
  11. http://jsfiddle.net/3F4pz/在需要检查数据的地方运行代码插入警报。 请记住,即使代码是自上而下也不意味着它以这种方式执行。而且我不确定你是怎么想出362的。