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 相关文章推荐
一个可绑定数据源的jQuery数据表格插件
Jul 17 Javascript
javascript垃圾收集机制与内存泄漏详细解析
Nov 11 Javascript
jquery中html、val与text三者属性取值的联系与区别介绍
Dec 29 Javascript
在浏览器中打开或关闭JavaScript的方法
Jun 03 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
Apr 06 Javascript
JS对象深度克隆实例分析
Mar 16 Javascript
基于require.js的使用(实例讲解)
Sep 07 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
Mar 22 Javascript
前端Electron新手入门教程详解
Jun 21 Javascript
vue路由传参的基本实现方式小结【三种方式】
Feb 05 Javascript
基于elementUI竖向表格、和并列的案例
Oct 26 Javascript
关于Javascript闭包与应用的详解
Apr 22 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中的多态性[译]
2011/08/02 PHP
input file获得文件根目录简单实现
2013/04/26 PHP
php二维数组用键名分组相加实例函数
2013/11/06 PHP
PHP与SQL语句常用大全
2016/12/10 PHP
ModelDialog JavaScript模态对话框类代码
2011/04/17 Javascript
JavaScript入门之对象与JSON详解
2011/10/21 Javascript
javascript 快速排序函数代码
2012/05/30 Javascript
JavaScript改变HTML元素的样式改变CSS及元素属性
2013/11/12 Javascript
Js nodeType 属性全面解析
2013/11/14 Javascript
node.js中的fs.appendFile方法使用说明
2014/12/17 Javascript
jquery通过ajax加载一段文本内容的方法
2015/01/15 Javascript
Javascript基础教程之关键字和保留字汇总
2015/01/18 Javascript
JavaScript中的Math.LN2属性用法详解
2015/06/12 Javascript
再JavaScript的jQuery库中编写动画效果的指南
2015/08/13 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
如何解决hover在ie6中的兼容性问题
2016/12/15 Javascript
微信小程序本地缓存数据增删改查实例详解
2017/05/24 Javascript
vue中for循环更改数据的实例代码(数据变化但页面数据未变)
2017/09/15 Javascript
jQuery中库的引用方法
2018/01/06 jQuery
js实现3D旋转效果
2020/08/18 Javascript
详解Python中列表和元祖的使用方法
2015/04/25 Python
详解Python import方法引入模块的实例
2017/08/02 Python
windows下python和pip安装教程
2018/05/25 Python
详解Django+uwsgi+Nginx上线最佳实战
2019/03/14 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
简单了解django文件下载方式
2020/02/10 Python
python函数调用,循环,列表复制实例
2020/05/03 Python
基于python模拟TCP3次握手连接及发送数据
2020/11/06 Python
使用HTML5 Canvas API中的clip()方法裁剪区域图像
2016/03/25 HTML / CSS
Vans英国官方网站:美国南加州的原创极限运动潮牌
2017/01/20 全球购物
日本乐天官方海外转运服务:Rakuten Global Express
2018/11/30 全球购物
中专自荐信
2013/10/13 职场文书
社区学雷锋活动策划方案
2014/01/30 职场文书
教师师德表现自我评价
2015/03/05 职场文书
乡镇团委工作总结2015
2015/05/26 职场文书
分析并发编程之LongAdder原理
2021/06/29 Java/Android