我正在学习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;
谢谢。
答案 0 :(得分:6)
让我们一步一步地分析。
第一个电话是mystery
,参数为3
。
mystery
做什么?它定义了一个变量secret
,其值为4
,然后将2
添加到input
。
所以在mystery
的前两行之后,你有:
secret = 4;
input = 5;
然后你有一个名为mystery2
的嵌套函数,它接受一个名为multiplier
的参数。在第一行中,它将input
与multiplier
相乘,然后返回secret * multiplier
。我们不知道multiplier
的值,但我们执行知道值secret
和input
。你可能想知道那是怎么回事。好吧,在JavaScript中创建闭包时,它是词法绑定到当前作用域。这只是一种奇特的方式,说闭包“知道”在闭包本身创建的同一范围内创建的所有局部变量。此行为也适用于嵌套函数,这就是为什么它们可以在JavaScript中充当闭包的原因。那么这意味着mystery2
,当它最终被调用时,secret
设置为4
,input
设置为5
。因此,mystery2
从mystery
返回,它知道这两个值。因此,执行后,变量hidden
不包含值,而是包含对mystery2
实例的引用,其中secret
和input
的值是我之前提到过。
这有什么好处?优点是,您可以拥有多个mystery2
副本,这些副本根据传递给input
的内容“了解”mystery
的不同值。所以在这里,mystery
有点像mystery2
的构造函数。
现在我们hidden
指向mystery2
的实例。因此,在这种情况下,hidden
是我们自己的mystery2
特殊副本的别名。
在下一行中,您调用mystery3
并传入hidden
作为参数。 mystery3
内发生了什么?好mystery3
接受一个名为param
的参数,然后它执行与mystery
类似的操作;它返回一个函数。这个功能有什么作用?它接受一个名为bonus
的参数。然后它param(6) + bonus
。
这是什么意思?
什么是param
?这是传递给mystery3
的论点。由于mystery4
的行为类似于闭包,因此它“知道”param
。但实际上是,什么是param
?好吧,param
是hidden
,它指向我们mystery2
的特殊实例!现在,我们实际评估mystery2
:我们使用6
的参数调用它,它将是multiplier
的值。所以现在你有multiplier *= input
。 input
“知道”的mystery2
值为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
}
什么是param
?好吧,这基本上是mystery2
:
function mystery2 ( multiplier ) {
multiplier *= input;
return secret * multiplier;
}
让我们再看一遍计算。当我们致电param(6)
时,我们multiplier
内的6
基本上设置为mystery2
。 mystery2
“知道”input
是5
(这是我们在mystery
内计算的内容)。因此multiplier *= input
表示multiplier
现在是30
。然后我们secret * multiplier
4 * 30
,120
。param(6)
。因此120
的返回值为bonus
。要此值,我们会在mystery4
中添加mystery4
。我们使用2
参数调用120 + 2
,因此我们有122
,这意味着最终结果为{{1}}。
希望这会帮助你!