JS尾递归的实现方法及代码优化技巧


Posted in Javascript onJanuary 19, 2019

本文实例讲述了JS尾递归的实现方法及代码优化技巧。分享给大家供大家参考,具体如下:

在学习数据结构和算法的时候,我们都知道所有的递归都是可以优化成栈+循环的。

对于特定的递归函数,一般我们都是手动对它们进行优化的。

在学习scala的时候,接触到尾递归的概念。我们只要将递归写成尾递归方式,编译器会自动帮助我们优化。

ps:并不是所有的递归都可以改写成尾递归

在js中,尾递归通常会被解释器优化。然而,并不是所有的js解释器都支持尾递归优化。

对于不支持尾递归优化的环境,我们需要手动将递归优化成栈+循环。

这里实现了一个通用的方法,将尾递归优化成栈+循环。

代码摘自阮一峰的《ECMAScript入门》这本书。

具体代码如下

function tco(f) {
  var value;
  var active = false;
  var accumulated = [];
  return function accumulator() {
    accumulated.push(arguments);
    if(!active) {
      active = true;
      while(accumulated.length) {
        value = f.apply(this, accumulated.shift());
      }
      active = false;
      return value;
    }
  };
}
var sum = tco(function(x, y) {
  if(y > 0) {
    return sum(x + 1, y - 1);
  } else {
    return x;
  }
});
let res = sum(1, 5)
console.info(res);

这段代码非常精妙!

分析

已知,任何递归可以写成循环+栈。

实现将任何尾递归转换成循环+栈执行而不需要针对每个尾递归函数写一个实现版本的思路。

困难在于,任何尾递归,通用实现。而不是针对某一个递归函数。

要点:

栈中保存的数据,正是递归函数的参数。

通用实现,那就必须依赖原来的递归函数,循环的终止条件,正是递归的结束条件。

要将递归函数的参数入栈,而不修改原来的递归函数,就必须用一个函数代替递归函数被调用,从而取得函数入参。

递归函数的终止条件,每一个递归函数都不一样,但是如果递归函数没有被再次调用,说明已达到终止条件。即终止条件和递归函数的调用有关联。而递归函数每次调用,都会将参数入栈。所以可以根据栈中是否有元素,推断是否达到终止条件。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript preload&lazy load
May 13 Javascript
jQuery Tips 为AJAX回调函数传递额外参数的方法
Dec 28 Javascript
基于jquery & json的省市区联动代码
Jun 26 Javascript
自动设置iframe大小的jQuery代码
Sep 11 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
Aug 01 Javascript
javascript ASCII和Hex互转的实现方法
Dec 27 Javascript
详解Chai.js断言库API中文文档
Jan 31 Javascript
vue实现密码显示隐藏切换功能
Feb 23 Javascript
vue2.0获取鼠标位置的方法
Sep 13 Javascript
微信小程序如何访问公众号文章
Jul 08 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 Javascript
解决vue+router路由跳转不起作用的一项原因
Jul 19 Javascript
javascriptvoid(0)含义以及与"#"的区别讲解
Jan 19 #Javascript
js实现延迟加载的几种方法详解
Jan 19 #Javascript
15分钟深入了解JS继承分类、原理与用法
Jan 19 #Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
Jan 19 #Javascript
js的各种数据类型判断的介绍
Jan 19 #Javascript
JavaScript实现与使用发布/订阅模式详解
Jan 19 #Javascript
Vuex中的State使用介绍
Jan 19 #Javascript
You might like
77A一级收信机修理记
2021/03/02 无线电
如何提高MYSQL数据库的查询统计速度 select 索引应用
2007/04/11 PHP
zend framework多模块多布局配置
2011/02/26 PHP
PHP 登录完成后如何跳转上一访问页面
2014/01/14 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
php post大量数据时发现数据丢失问题解决方法
2015/06/20 PHP
UTF-8正则表达式如何匹配汉字
2015/08/03 PHP
如何在旧的PHP系统中使用PHP 5.3之后的库
2015/12/02 PHP
PHP 7.0新增加的特性介绍
2017/06/08 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
HR vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
学习jquery必备 api中英文对照的chm手册 下载
2007/05/03 Javascript
用js脚本控制asp.net下treeview的NodeCheck的实现代码
2010/03/02 Javascript
解决遍历时Array.indexOf产生的性能问题
2012/07/03 Javascript
jQuery.buildFragment使用方法及思路分析
2013/01/07 Javascript
javascript鼠标跟随运动3种效果(眼球效果,苹果菜单,方向跟随)
2016/10/27 Javascript
微信小程序-拍照或选择图片并上传文件
2017/01/06 Javascript
webuploader实现上传图片到服务器功能
2018/08/16 Javascript
node Buffer缓存区常见操作示例
2019/05/04 Javascript
node.js处理前端提交的GET请求
2019/08/30 Javascript
[01:38]DOTA2 2015国际邀请赛中国区预选赛 Showopen
2015/06/01 DOTA
[01:32]TI珍贵瞬间系列(一)
2020/08/26 DOTA
python爬虫框架scrapy实现模拟登录操作示例
2018/08/02 Python
对Python的多进程锁的使用方法详解
2019/02/18 Python
python生成随机红包的实例写法
2019/09/02 Python
加拿大在线眼镜零售商:SmartBuyGlasses加拿大
2019/05/25 全球购物
电大自我鉴定
2013/10/27 职场文书
成人教育自我鉴定
2013/11/01 职场文书
工商企业管理实习自我鉴定
2013/12/04 职场文书
会计电算化专业毕业生求职信范文
2013/12/10 职场文书
庆元旦广播稿
2014/02/10 职场文书
法律顾问服务方案
2014/05/15 职场文书
记账会计岗位职责
2014/06/16 职场文书
办公室主任岗位职责范本
2015/03/31 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书
python基于机器学习预测股票交易信号
2021/05/25 Python