我试图理解 NodeJS 中的递归函数,但我仍然对以下代码和输出感到困惑:
var firstf = function () {
var counter = 0;
return function () {
console.log("counter = " + counter);
return counter += 1;
}
};
var add = firstf();
add();//output 0
add();//output 1
add();//output 2
firstf()();//output 0
firstf()();//output 0
firstf()();//output 0
我可以理解三个add()函数输出0,1,2,但我不明白为什么三个firstf()()输出0,0,0。 请问两个()()是什么意思?
还有一个后续问题:对于这一行:var add = firstf();
变量 add will 将返回函数表示为:
function () {
console.log("counter = " + counter);
return counter += 1;
}
好的,问题是这个函数怎么能看到变量计数器,因为计数器在上层,没有在这个内部函数中定义。
这里没有递归。 递归是函数调用自身的地方。 这称为闭包。 因为内部函数包含对外部函数作用域中变量的引用。 这是一篇关于闭包的好文章。 来自那篇文章:
闭包是捆绑在一起(封闭)的函数的组合 参考其周围状态(词汇环境)。
在 换句话说,闭包允许您访问外部函数的作用域 从内部函数。在 JavaScript 中,每次都会创建闭包 在创建函数时创建一个函数。要使用闭包, 在另一个函数中定义一个函数并公开它。
要公开 函数,返回它或将其传递给另一个函数。内部函数 将有权访问外部函数作用域中的变量,甚至 在外部函数返回后。
现在,让我们确切地诊断firstf()()
发生了什么。
首先叫firstf()
. 这会将内部counter
初始化为0
并返回一个新函数。
然后,第二个()
执行返回的函数,该函数返回0
counter
的值并将其递增。
然后,您再次致电firstf()()
。 这会初始化一个新的counter
变量0
并返回一个新函数。 然后,第二个()
调用该函数并返回新的counter
值0
,然后递增它。
所以,这就解释了为什么连续打电话给firstf()()
只是不断返回0
。 每次你都会创建一个新函数和一个新的计数器变量。
当您执行var add = firstf();
然后调用add()
时,您将存储返回的函数,然后一遍又一遍地调用相同的函数。 这将继续使用相同的内部counter
变量,因此您将看到返回值随着该内部counter
变量每次递增而上升。
请问两个()()是什么意思?
每个()
都尝试执行一个函数。 在firstf()()
中,第一个()
执行firstf()
并得到它返回的函数。 然后,第二个()
执行返回的函数并获取它返回的任何内容(计数器值)。