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 相关文章推荐
用js实现计算代码行数的简单方法附代码
Aug 13 Javascript
JQuery 初体验(建议学习jquery)
Apr 25 Javascript
替代window.event.srcElement效果的可兼容性的函数
Dec 18 Javascript
css样式标签和js语法属性区别
Nov 06 Javascript
IE与FF下javascript获取网页及窗口大小的区别详解
Jan 14 Javascript
微信小程序 页面跳转如何实现传值
Apr 05 Javascript
angular+webpack2实战例子
May 23 Javascript
完美解决手机网页中输入框被输入法遮挡的问题
Dec 19 Javascript
express默认日志组件morgan的方法
Apr 05 Javascript
SSM+layUI 根据登录信息显示不同的页面方法
Sep 20 Javascript
js判断浏览器的环境(pc端,移动端,还是微信浏览器)
Dec 24 Javascript
js实现随机点名
Jan 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
php无限极分类实现的两种解决方法
2013/04/28 PHP
Centos7.7 64位利用本地完整安装包安装lnmp/lamp套件教程
2021/03/09 Servers
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
javascript获取web应用根目录的方法
2014/02/12 Javascript
jQuery中offsetParent()方法用法实例
2015/01/19 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
JS实现选择TextArea内文本的方法
2015/08/03 Javascript
Extjs实现下拉菜单效果
2016/04/01 Javascript
JavaScript自定义函数实现查找两个字符串最长公共子串的方法
2016/11/24 Javascript
easy ui datagrid 从编辑框中获取值的方法
2017/02/22 Javascript
Node.js  事件循环详解及实例
2017/08/06 Javascript
JSONP原理及应用实例详解
2018/09/13 Javascript
Vue源码学习之关于对Array的数据侦听实现
2019/04/23 Javascript
微信小程序基于Taro的分享图片功能实践详解
2019/07/12 Javascript
Vue  webpack 项目自动打包压缩成zip文件的方法
2019/07/24 Javascript
原生js canvas实现鼠标跟随效果
2020/08/02 Javascript
js实现微信聊天界面
2020/08/09 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
Python读大数据txt
2016/03/28 Python
Python简单操作sqlite3的方法示例
2017/03/22 Python
详谈python http长连接客户端
2017/06/12 Python
Python实现随机漫步功能
2018/07/09 Python
对python的输出和输出格式详解
2018/12/08 Python
python 执行文件时额外参数获取的实例
2018/12/18 Python
Django用户认证系统 User对象解析
2019/08/02 Python
Python在OpenCV里实现极坐标变换功能
2019/09/02 Python
Python三元运算与lambda表达式实例解析
2019/11/30 Python
python中re模块知识点总结
2021/01/17 Python
Charles & Colvard官网:美国莫桑石品牌
2019/06/05 全球购物
Traffic People官网:女式花裙、上衣和连身裤
2020/10/12 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
春节联欢晚会主持词范文
2014/03/24 职场文书
缅怀革命先烈演讲稿
2014/05/14 职场文书
公司领导班子对照检查存在问题整改措施
2014/10/02 职场文书
管理者们如何制定2019年的工作计划?
2019/07/01 职场文书
Win11查看设备管理器
2022/04/19 数码科技