在node.js中,全局变量的值在堆栈被无限递归超越后神秘地重置
Global variable value mysteriously reset after stack exceed by infinite-wannabe recursion in node.js
我想计算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控制台之间仍然存在差异,其中值保留未处理的异常
每个交互模式的行为都与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
的全局值更新为在我们的测试函数的执行上下文中计算的值。
相关文章:
- 数组在递归方法中设置为null
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 递归使用 eval() 是检查程序执行的好方法吗?
- 使用递归、Ramda.js和无点样式重构字符串的getPermutations()
- 递归深度比较
- Eloquent JavaScript递归示例如何终止为返回1,但仍然输出指数值
- 递归函数中断
- 如何递归地获取嵌套对象中所有子对象的列表
- JavaScript 素数搜索无限递归
- 在递归生成器函数中,yield后面的*(星号/星号)语法意味着什么
- 递归|两个函数名
- 有没有一种方法可以在Javascript中进行可变递归currying
- 如何对不同的表递归使用以下代码
- 将jQuery对象传递到setTimeout递归函数中
- 有更好的方法吗?(递归解析HTML unicode实体)
- 为什么递归生成器函数没有't在ES2015工作
- 使用递归实现加性持久性
- 递归显示n元树
- 如何超越递归限制
- 在node.js中,全局变量的值在堆栈被无限递归超越后神秘地重置