需要帮助了解Javascript关闭

leo*_*ini 2 javascript closures

我正在学习javascript闭包,并且很难理解这个概念.如果有人能够引导我完成这个例子,即输入和输出的进展,我会很感激.

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;
}
results;
Run Code Online (Sandbox Code Playgroud)

谢谢.

Viv*_*ath 6

让我们一步一步地分析.

第一个调用是mystery带有参数3.

怎么mystery办?它secret使用值定义变量,4然后将其添加2input.

所以在前两行之后mystery,你有:

secret = 4;
input = 5;
Run Code Online (Sandbox Code Playgroud)

然后你有一个嵌套的函数mystery2,它接受一个名为的参数multiplier.在第一行就乘inputmultiplier,然后返回secret * multiplier.我们不知道的值multiplier,但是我们知道的价值观secretinput.你可能想知道那是怎么回事.好吧,在JavaScript中创建闭包时,它在词法上绑定到当前作用域.这只是一种奇特的方式,说闭包"知道"在闭包本身创建的同一范围内创建的所有局部变量.此行为也适用于嵌套函数,这就是为什么它们可以在JavaScript中充当闭包的原因.所以这意味着mystery2,当它最终被调用时,将secret设置为4input设置为5.所以mystery2,这知道这两个值,从中返回mystery.所以执行后,变量hidden不包含价值,而不是它包含的实例的引用mystery2,其中的价值观secretinput是我前面提到的那些.

这有什么好处?优点是你可以有多个副本mystery2,input根据传入的内容"知道"不同的值mystery.所以在这里,mystery有点像一个构造函数mystery2.

现在我们hidden指向一个实例mystery2.所以在这种情况下hidden是我们自己的特殊副本的别名mystery2.

在下一行中,您将调用mystery3hidden作为参数传入.里面发生了什么mystery3?好吧mystery3接受一个叫做的参数param,然后它做类似的事情mystery; 它返回一个函数.这个功能有什么作用?它接受一个名为的参数bonus.然后呢param(6) + bonus.

那是什么意思?

什么是param?这是传递给的论点mystery3.由于mystery4表现得像一个闭包,它"知道" param.但实际上,是什么param?嗯,paramhidden,这指向我们的特殊实例mystery2!现在这里是我们实际评估的地方mystery2:我们用一个参数来调用它6,它的值是multiplier.所以现在你有multiplier *= input.的值inputmystery2"知道"是5.所以我们基本上有6 * 5,这意味着multiplier现在设置为30.然后我们返回secret * multiplier,这是4 * 30,这是120.那么这意味着param(6)返回120,然后我们添加bonus.请记住,只有在我们实际执行时才会发生这种情况mystery4.

我们什么时候执行mystery4?我们打电话后mystery3,我们会返回一份副本mystery4,然后分配给jumble.之后我们打电话jumble(2).那是什么jumble?基本上是这样的:

function mystery4(bonus) {
    return param(6) + bonus
}
Run Code Online (Sandbox Code Playgroud)

什么是param?嗯,这基本上是mystery2:

function mystery2 ( multiplier ) { 
    multiplier *= input;
    return secret * multiplier;
}
Run Code Online (Sandbox Code Playgroud)

我们再来看看计算结果.当我们打电话时param(6),我们基本上已经multiplier设置为6内部mystery2.mystery2"知道" input就是5(这是我们在里面计算的mystery).所以multiplier *= input,意味着multiplier现在30.然后我们做的secret * multiplier,这是4 * 30,这是120.所以返回值param(6)120.为了这个价值,我们添加bonusmystery4.我们mystery4用一个参数调用2,所以我们有120 + 2,这意味着最终的结果是122.

希望这可以帮助你!