【前端】递归之引起堆栈溢出解决方案

简介:递归引起错误VM434:1 Uncaught RangeError: Maximum call stack size exceeded

优化前递归

```function obj(x,y){    if(y>1){    return obj(x + 1,y - 1);    }else{    return x;    }}/**执行方法**/obj(2,1000); //1001obj(2,100000); //Uncaught RangeError: Maximum call stack size exceeded```复制代码

当递归大于一定数量后出现了堆栈溢出情况(这里是大于10000次出现了)

解决方案1

蹦床函数(trampoline)可以将递归执行转为循环执行。

functiontrampoline(f){while(f && f instanceof Function){        f = f();    }returnf;}functionobj(x,y){if(y > 1){returnobj.bind(null,x + 1,y - 1);    }else{returnx;    }}trampoline(obj(2,1000)); //1001trampoline(obj(2,100000)); //100001复制代码

蹦床函数他接受一个函数f为参数,只要f执行后返回一个函数,就继续执行。

注意:这里返回的是一个函数,然后继续执行函数,而不是函数里面调函数,避免了递归执行调用栈过大的问题

蹦床函数不是真正的尾递归优化。

解决方案2

functiontco(f){    var value,        active=false,        accumulated=[];returnfunctionaccumulator(){        accumulated.push(arguments);if(active=false){            active=true;while(accumulated.length){                value=f.apply(this,accumulated.shift())            }            active=false;returnvalue;        }    }}var obj=tco(function(x,y){if(y > 1){returnobj(x + 1, y - 1);    }else{returnx;    }})/**执行方法**/obj(2,1000); //1001obj(2,100000); //100001复制代码

上面代码中,tco函数是尾递归优化的实现,他主要在于active的状态,只要进入递归优化过程这个状态就激活了,然后每一轮obj3都返回undefined,所以就避免了递归执行;而accumulated数组存放每一轮obj3执行的参数,总是有值的,保证了accumulator函数内部while的循环总是执行。这样递归就改成了训话,后一轮参数取代前一轮参数,保证栈只有一层。

作者:梁青竹

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.函数参数的默认值 (1).基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
    赵然228阅读 847评论 0 0
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    陈老板_阅读 529评论 0 1
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 3,726评论 0 1
  • 洛洛姨阅读 142评论 0 4
  • 经验知识的萃取与提炼 工作方法论是关于职业生涯思考的结果。如何总结个人经验,生活经验,亲子教育,工作总结,如何证明...
    独自美丽的SHOW阅读 1,285评论 2 6

友情链接更多精彩内容