我想计算 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
。
这是正确的行为吗?这里发生了什么?例如在 chromium (v14) 中,c
按预期保存最终计数。
更新
事实证明,以上仅在交互模式下有效。当代码从文件中执行时,函数包含在 try-catch block 中(以防止过早退出),c 值是正确的..
c = 0;
try {
(function f() { c++; f() })();
} catch(e) {};
console.log(c);
但是,交互式 node.js 和 chromium javascript 控制台之间仍然存在差异,其中值在未处理的异常中幸存下来
最佳答案
每种交互模式的行为都与 JavaScript 文件的标准执行略有不同(Isaac Schlueter 在某处写道:“我从未见过没有至少一点魔法的 REPL”)。交互模式必须评估文本,这通常在不同的上下文中运行代码。
在 Node.JS 的情况下,每个命令都在其自己的上下文中执行,然后 REPL 负责将结果返回给我们。如果由于某些错误我们在命令中失败,我们变量的值将保持不变(因为更改的变量在执行上下文中“死亡”)。当我们以标准方式运行 JavaScript 文件时,我们没有这个单独的执行上下文,我们直接更改变量。
您可以更改示例以手动创建错误并发挥作用:
c=0;
(function f(x){ c++; if(x) f(x-1); else throw new Error(); })(10);
只要代码执行出错,c
的最终值在 REPL 中将为 0。由于错误 REPL 无法将 c
的全局值更新为在我们的测试函数的执行上下文中计算的值。
关于javascript - 全局变量值在 node.js 中的无限递归超过堆栈后神秘地重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6861843/