我想使用全局值递增计算node.js(v0.4.10)中无限递归函数的步骤。但是,计数总是假装为零
> c = 0
> (function f() { c++; console.log(c); f() })();
1
2
...
18648
RangeError: Maximum call stack size exceeded
> c
0
从函数中将c
值记录到控制台显示该值实际上是递增的,但不知何故,它最终会在该堆栈事故后重置。即使使用global.c
而不是c
。
这是正确的行为吗?这里发生了什么?例如在铬(v14)中,c
按预期保留最终计数。
事实证明,上述仅在交互模式下有效。当代码从文件执行,并且函数包含在try-catch块中(以防止过早退出)时,c值是正确的。
c = 0;
try {
(function f() { c++; f() })();
} catch(e) {};
console.log(c);
然而,交互式node.js和chromium javascript控制台之间存在差异,其中值存在未处理的异常
答案 0 :(得分:2)
每个交互模式的行为都与JavaScript文件的标准执行略有不同(Isaac Schlueter在某处写道:“我从未见过一个没有至少一点点魔法的REPL < / em>的“)。交互模式必须评估文本,该文本通常在不同的上下文中运行代码。
在Node.JS的情况下,每个命令都在自己的上下文中执行,然后REPL会注意返回结果。如果由于某些错误导致命令失败,则变量的值保持不变(因为在执行的上下文中已更改的变量'die')。当我们运行JavaScript文件标准方式时,我们没有这个单独的执行上下文,我们直接更改我们的变量。
您可以更改示例以手动创建错误并发挥作用:
c=0;
(function f(x){ c++; if(x) f(x-1); else throw new Error(); })(10);
只要代码执行错误,c
的最终值在REPL中将为0。由于错误,REPL无法将c
的全局值更新为在测试函数的执行上下文中计算的值。