【转自知乎】javascript优化堆栈溢出的方法

以下是普通的递归形式的计算阶乘的函数:

function factorial1(num)
{
    return num<1 ? 1 : num*factorial1(num-1);
}
console.log(factorial1(5)); //结果为120

但是进行长递归时,每次调用递归函数都会消耗资源存储递归产生的变量且在递归过程中无法释放,于是将该函数进行尾递归优化

function factorial2(num,res=1)
{
    return num<1 ? res : factorial2(num-1,res*num);
}
console.log(factorial2(5)); //结果为120

相比factorial1,factorial2的参数res保存了临时的计算结果, 函数返回回溯时不需要做任何额外的计算,但是仍然会进行递归调用导致调用栈增长,于是将递归改为循环:

//递归转化为循环的形式
function trampoline(f)
{
    let func = f;
    while (typeof func === 'function'){
        func = func();
    }
    return func;
}

function fac(num,res)
{
    return num<1? res : fac.bind(null, num-1, res*num);
}

function factorial3(num)
{
    return trampoline(fac.bind(null, num, 1));
}

console.log(factorial3(5)); //结果为120
bind方法会创建一个绑定函数,第一个参数的值为函数域内this的指向, 第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数这里fac函数并不会直接进行递归调用而是返回下一步的调用交给trampoline函数来循环调用, 这样调用栈就不会增长了,此方法可以解决一些浏览器进行长递归由于没有立即释放变量导致的堆栈溢出问题
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值