首先,调用函数的方式会让我失望。如何使用两个单独的parens调用函数,如本示例中的那个?
addTogether(4)(3)
最后,有人可以在if语句中解释闭包的工作原理(请参阅下面的完整代码)?
if(a) {
return function(y) {
if(checkIfNum(y)) {
return a + y;
} else {
return undefined;
}
};
如果我们这样打addTogether()
:
addTogether(4)(3)
,我了解论据a
设置为4
但不确定y
如何设置为3
。
function addTogether() {
function checkIfNum(num) {
return typeof num === 'number' ? num : undefined;
}
var a = checkIfNum(arguments[0]);
var b = checkIfNum(arguments[1]);//if there is no second argument, var b = undefined;
if(arguments.length > 1) {
return a && b ? a + b : undefined;
} else {
if(a) {
return function(y) {
if(checkIfNum(y)) {
return a + y;
} else {
return undefined;
}
};
} else {
return undefined;
}
}
}
console.log(addTogether(4)(3));//7
在第一次调用时,addTogether(4),'var a = checkIfNum(arguments [0]);'解析为'var a = 4'。 addTogether()的第一次调用导致我们的匿名函数(y)被调用并返回到主函数addTogether()。当调用匿名函数(y)时,JavaScript会搜索“y”的值。 JavaScript如何确定'3'将是'y'的值?我的猜测是,在第一次调用addTogether()或addTogether(4)时,与addTogether()关联的参数对象被设置为值4.一旦将4传递给函数addTogether(),我们现在有了'a '= 4被困在addTogether()创建的闭包中,同时,基本上我们发生了三件事:#1:'a'= 4,#2:addTogether()的参数现在设置为值3或addTogether(3),#3:返回并调用匿名函数(y),导致JavaScript搜索'y'的值。 JavaScript看到在这个确切的时间点,addTogether()的参数设置为3的值,因此JavaScript将'y'的值设置为3. JavaScript如何知道将'y'设置为3的值?当一个函数在另一个函数内部被调用时,JavaScript会自动设置参数的值,因为缺少更好的单词,“子”函数是否为“父”函数的参数值?有什么关于我在这里缺少的参数对象吗?
答案 0 :(得分:3)
好问题。大约两年前,我记得在同一个例子上摸不着头脑。
对于您的第一个问题,“如何使用两个单独的parens调用函数,例如本示例中的函数?”:
这是唯一可能的,因为addTogether
会返回另一个函数。然后你将该函数传递给另一个整数3.然后将它们相加以得到7.
然后你询问闭包:当你在一个范围内添加额外的范围时,会形成一个闭包,使得内部范围可以访问外部范围中的值。在这种情况下,在函数内声明函数时会形成闭包。
对于您的第二个问题:“我理解参数a设置为4,但y设置为3”:
这是函数addTogether
的逻辑:
1)检查是否提供了一个或两个参数。
2)如果提供了两个参数,则返回添加数字,如果它们都是数字。
3)如果只有一个,则返回一个带有整数的匿名函数,并将其输入添加到匿名函数可用的变量a
,因为它是封闭声明a
的外部函数。
这是关闭形成的地方。这个匿名函数,因为它在外部函数addTogether
的范围内,可以访问所有外部函数的属性,包括a
和方法checkIfNum
。
在您的实际案例中:
1)您提供一个参数3,因此addTogether
返回一个匿名函数。
2)你使用值3来调用这个匿名函数。这最终运行匿名函数中的逻辑,首先检查3是否为数字,然后加3到4,返回7.
我喜欢JavaScript。