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 eval和JSON之间的联系
Dec 31 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
Jan 15 Javascript
JavaScript检查某个function是否是原生代码的方法
Aug 20 Javascript
使用JavaScript链式编程实现模拟Jquery函数
Dec 21 Javascript
jQuery unbind()方法实例详解
Jan 19 Javascript
jquery表单插件Autotab使用方法详解
Jun 24 Javascript
基于jQuery实现页面搜索功能
Mar 26 Javascript
详解JavaScript树结构
Jan 09 Javascript
AngularJS学习第二篇 AngularJS依赖注入
Feb 13 Javascript
重新理解JavaScript的六种继承方式
Mar 24 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
May 22 Javascript
Electron+vue从零开始打造一个本地播放器的方法示例
Oct 27 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判断类是否存在函数class_exists用法分析
2014/11/14 PHP
php自动载入类用法实例分析
2016/06/24 PHP
购物车实现的几种方式优缺点对比
2018/05/02 PHP
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
2011/07/10 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
2013/11/19 Javascript
JS实现跟随鼠标闪烁转动色块的方法
2015/02/26 Javascript
使用console进行性能测试
2015/04/27 Javascript
JS模态窗口返回值兼容问题的完美解决方法
2016/05/28 Javascript
第四篇Bootstrap网格系统偏移列和嵌套列
2016/06/21 Javascript
Angular2 (RC4) 路由与导航详解
2016/09/21 Javascript
详解React-Todos入门例子
2016/11/08 Javascript
实例解析jQuery中如何取消后续执行内容
2016/12/01 Javascript
JavaScript简单生成 N~M 之间随机数的方法
2017/01/13 Javascript
浅谈JS验证表单文本域输入空格的问题
2017/02/14 Javascript
JS计算输出100元钱买100只鸡问题的解决方法
2018/01/04 Javascript
开发一个Parcel-vue脚手架工具(详细步骤)
2018/09/22 Javascript
js变量值传到php过程详解 将php解析成数据
2019/06/26 Javascript
JS实现打字游戏
2019/12/17 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
2020/05/25 Javascript
Python缩进和冒号详解
2016/06/01 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
Python求两个字符串最长公共子序列代码实例
2020/03/05 Python
Python3操作读写CSV文件使用包过程解析
2020/04/10 Python
Numpy 多维数据数组的实现
2020/06/18 Python
django和flask哪个值得研究学习
2020/07/31 Python
HTML5为输入框添加语音输入功能的实现方法
2017/02/06 HTML / CSS
乌克兰品牌化妆品和香水在线商店:Bomond
2020/01/14 全球购物
你常见到的runtime exception
2016/09/05 面试题
"序列点" 是什么
2016/07/29 面试题
人事专员岗位职责说明书
2014/07/30 职场文书
离婚协议书怎样才有法律效力
2014/10/10 职场文书
2014年维修电工工作总结
2014/11/20 职场文书
员工离职感谢信
2015/01/22 职场文书
物业工程部主管岗位职责
2015/04/16 职场文书
2016年情人节广告语
2016/01/28 职场文书
小学2016年第十八届推普周活动总结
2016/04/05 职场文书