有人能解释一下这个javascript闭包是如何工作的吗?

Can someone explain how this javascript closure works?

本文关键字:何工作 工作 闭包 能解释 一下 javascript      更新时间:2023-09-26

好的,我开始学习闭包是如何工作的......这个问题我已经纠结了好几个小时了。我只是不明白它是怎么工作的。

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

    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的?

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

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

var hidden = mystery(3);

现在,mystery返回一个函数。但是它实际返回什么呢?一个简单的alert(hidden)语句将告诉您它返回

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

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

  • multiplier是一个参数,它的值将是当调用
  • 时传递给它的值。
  • 但是input的值是多少呢?
  • secret ?

这就是闭包发挥作用的地方。input的值将从创建该函数的作用域中获取。创建这个函数时,inputsecret的值是多少?让我们再来看看mystery:

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

所以我们发现input的值实际上是5,而secret的值是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

我已经更改了一些名称,使其更易于阅读,并添加了一些注释来指出行执行时的值。

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. mystery(3) ->输入将被设置为5
  2. 然后返回神秘函数句柄
  3. 将句柄传递给mystery3
  4. 返回在其中访问mystery2句柄的mystery4句柄
  5. 执行mystery4并设置奖励参数为2
  6. 将乘数参数设置为6时执行mystery2
  7. 其中乘以5 = 30
  8. 然后将秘密4乘以30 = 120
  9. 返回谜题4中添加2(奖励)的120
  10. 瞧122

http://jsfiddle.net/3F4pz/在需要检查数据的地方运行代码插入警报。请记住,即使代码是自上而下的,也不意味着它是这样执行的。我不知道你是怎么想到362的