![](/img/trans.png)
[英]Can anyone please explain me the following function from eloquent javascript
[英]Explain this javascript function from Eloquent Javascript
我很难跟上这个功能。 我不明白的变量是如何start
恢复到16达到26的值大于24后。
function findSequence(goal) {
function find(start, history) {
if (start == goal)
return history;
else if (start > goal)
return null;
else
return find(start + 5, "(" + history + " + 5)") ||
find(start * 3, "(" + history + " * 3)");
}
return find(1, "1");
}
print(findSequence(24));
好的,在看了一段时间后,我有几个问题可能会澄清一些事情:
1)说每个查找调用都跟踪它自己的起始值是否是正确的陈述? 例如,当调用find(1)时,它的起始值为1,当调用find(1 + 5)时,find(1)的起始值仍为1,但find(1 + 5)现在具有它的起始值为6。
2)即使我看到它打印出来,我也很难跟踪堆栈跟踪。 这就是我查看它的方式:
find(1)调用find(1 + 5)// start = 1
find(6)调用find(6 + 5)// start = 6,Passes
find(11)调用find(11 + 5)// start = 11,Passes
find(16)调用find(16 + 5)// start = 16,Passes
find(21)调用find(21 + 5)// start = 21,失败
因为find(21 + 5)返回null,所以它尝试调用find(21 * 3),它也返回null。
这是我遇到的部分,如果发现(21 + 5)和找到(21 * 3)返回null,接下来如何调用find(16 * 3)。 为什么不再找(16 + 5)?
在find(16)中调用find(21 + 5)和find(21 * 3)并且因为那些返回null到调用函数时,它有什么可做的,它执行了||的第二部分 找到的陈述(16 * 3)。
也许你并不完全相信,但你明白了。
关于议题1,它是正确的说, start
值沿着内来电保存。 这就像每个调用都有自己的“上下文” - 即使你修改变量和参数值,这也不会被带到外部函数调用。 这是范围。
问题2似乎与短路布尔评估有关。 行为正如您所描述的那样:一旦表达式位于||
左侧 运算符返回“truey”,右边的表达式将不会被评估。 反之亦然:如果左表达式为“falsey”,则解释器将继续评估正确的表达式。 结果值将是第一个非假名值,或链中的最后一个值。
所以我认为你得到了一切!
我修改了原始脚本,因此它打印了一个调用跟踪。 在这里看到它。
这是一个部分跟踪,其中start
值在进一步显示后“减少”为16:
该函数在16分支下稍微进一步,然后它停止,恢复到上部调用,其中start
为11.然后它继续尝试11 * 3的值start
,然后它再次停止,依此类推。
这是一个不同的变量。 只要调用特定的find(x),它的start值就不会影响start的任何其他实例。
当调用find(21)时,它返回null,因为find(26)和find(63)同样返回null,find(16)和find(11)返回null
当调用find(6)时,它调用find(11),返回null,因此它接下来调用find(24)。 在此调用的上下文中,start == 6,因此它继续start + 5并开始* 3。
find(6):
start = 6, history = (1 + 5)
find(6 + 5):
start = 11, history = ((1 + 5) + 5)
find(11 + 5):
start = 16, history = (((1 + 5) + 5) + 5)
... continued etc...
find(11 * 3):
start = 33, history = (((1 + 5) + 5) * 3)
<end>
find(6 * 3):
start = 24, history = ((1 + 5) * 3)
你不是在考虑递归分支。 看起来似乎开始上下抖动,但你只是到达一个递归树的底部并跳到另一个递归树。
通过电话:
递归树中的start
值( start+5
/ start*3
上的分支):
1
6---------+----------3
11----+--18 8-----+-----
16-+-33 23-+--48 13-+--24
21-+-80 28+69 18+39
26+63 23+90
28+69
当值过高时,查看每个分支如何结束,然后当处理向右跳转到下一个分支start
,您看到的start
值会下降。 找到'24'时处理停止。
(免责声明:我还没有完全检查所有的数学,但原则应该是合理的!)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.