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动态添加表格数据行(ASP后台数据库保存例子)
May 08 Javascript
jQuery+ajax中getJSON() 用法实例
Dec 22 Javascript
jQuery知识点整理
Jan 30 Javascript
深入解析JavaScript中的数字对象与字符串对象
Oct 21 Javascript
js实现动态加载脚本的方法实例汇总
Nov 02 Javascript
javascript实现随机显示星星特效
Jan 28 Javascript
angularJS模态框$modal实例代码
May 27 Javascript
vue-cli history模式实现tomcat部署报404的解决方式
Sep 06 Javascript
vue中对象数组去重的实现
Feb 06 Javascript
antd-日历组件,前后禁止选择,只能选中间一部分的实例
Oct 29 Javascript
Ajax是什么?Ajax高级用法之Axios技术
Apr 21 Javascript
js 实现Material UI点击涟漪效果示例
Sep 23 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
用php实现的下载css文件中的图片的代码
2010/02/08 PHP
ThinkPHP实现多数据库连接的解决方法
2014/07/01 PHP
Yii扩展组件编写方法实例分析
2015/06/29 PHP
php反射类ReflectionClass用法分析
2016/05/12 PHP
完美解决IE低版本不支持call与apply的问题
2013/12/05 Javascript
JS获取随机数函数可自定义最小值最大值
2014/05/08 Javascript
js图片轮播手动切换效果
2015/11/10 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
AngularJS 所有版本下载地址
2016/09/14 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
Javascript之深入浅出prototype
2017/02/06 Javascript
angularJs使用$watch和$filter过滤器制作搜索筛选实例
2017/06/01 Javascript
vue.js全局API之nextTick全面解析
2017/07/07 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
微信小程序图表插件wx-charts用法实例详解
2019/05/20 Javascript
vue用BMap百度地图实现即时搜索功能
2019/09/26 Javascript
JS常用排序方法实例代码解析
2020/03/03 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
vue打包静态资源后显示空白及static文件路径报错的解决
2020/09/02 Javascript
Python用GET方法上传文件
2015/03/10 Python
Python 多进程并发操作中进程池Pool的实例
2017/11/01 Python
Python进度条实时显示处理进度的示例代码
2018/01/30 Python
Python实现账号密码输错三次即锁定功能简单示例
2019/03/29 Python
numpy.linspace函数具体使用详解
2019/05/27 Python
Python实现二叉搜索树BST的方法示例
2019/07/30 Python
浅谈PyTorch的可重复性问题(如何使实验结果可复现)
2020/02/20 Python
python开根号实例讲解
2020/08/30 Python
C语言笔试题回忆
2015/04/02 面试题
介绍一下linux文件系统分配策略
2012/11/17 面试题
材料物理专业大学毕业生求职信
2013/10/15 职场文书
同事打架检讨书
2014/02/04 职场文书
安全月宣传标语
2014/10/07 职场文书
工作推荐信模板
2015/03/25 职场文书
爱心捐款活动总结
2015/05/09 职场文书
毕业赠语大全
2015/06/23 职场文书