Open YBFACC opened 4 years ago
递归的次数太多了,超过了程序承载的能力。
我通过一个简易的代码,来测试下函数调用栈的能力。
function f(n) { try { return f(n + 1) } catch (error) { console.log(n) } } f(1)
我的node环境上限大概是10000左右。
实际看一下调用栈。在浏览器中执行以下代码。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> test </body> <script> function factorial(n, total = 1) { console.trace() if (n === 1) return total return factorial(n - 1, n + total) } console.log(factorial(30000)) </script> </html>
可以看到函数调用栈里的数量逐渐增加。
现在对尾递归的支持并不好。浏览器只有Safari支持,而且你必须开启严格模式。
你可以使用这个网站来查看支持性。
特征
我们在Safari 中执行以下代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> test </body> <script> 'use strict' function factorial(n, total = 1) { console.trace() if (n === 1) return total return factorial(n - 1, n + total) } console.log(factorial(30000)) </script> </html>
可以看到成功运行了,并且函数调用栈道数量一直没有发生变化。
以下代码copy来自尾调用优化
function tailFactorial(n, total) { if (n === 1) return total; return tailFactorial(n - 1, n * total); } function factorial(n) { return tailFactorial(n, 1); } factorial(5) // 120
function currying(fn, n) { return function (m) { return fn.call(this, m, n); }; } function tailFactorial(n, total) { if (n === 1) return total; return tailFactorial(n - 1, n * total); } const factorial = currying(tailFactorial, 1); factorial(5) // 120
function factorial(n, total = 1) { if (n === 1) return total; return factorial(n - 1, n * total); } factorial(5) // 120
尾递归的后续探究
尾调用优化
尾递归(tail call optimisation)
尾递归解决的问题
递归的次数太多了,超过了程序承载的能力。
我通过一个简易的代码,来测试下函数调用栈的能力。
我的node环境上限大概是10000左右。
实际看一下调用栈。在浏览器中执行以下代码。
可以看到函数调用栈里的数量逐渐增加。
使用尾递归
现在对尾递归的支持并不好。浏览器只有Safari支持,而且你必须开启严格模式。
特征
测试
我们在Safari 中执行以下代码:
可以看到成功运行了,并且函数调用栈道数量一直没有发生变化。
例子
以下代码copy来自尾调用优化
参考
尾递归的后续探究
尾调用优化