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 特殊字符串
Feb 25 Javascript
JS制作简单的三级联动
Mar 18 Javascript
使用AngularJS编写较为优美的JavaScript代码指南
Jun 19 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
May 24 Javascript
jQuery实现公告新闻自动滚屏效果实例代码
Jul 14 Javascript
Angular4学习笔记之根模块与Ng模块
Sep 09 Javascript
js for终止循环 跳出多层循环
Oct 04 Javascript
自定义javascript验证框架示例【附源码下载】
May 31 Javascript
使用 Vue 实现一个虚拟列表的方法
Aug 20 Javascript
layui 地区三级联动 form select 渲染的实例
Sep 27 Javascript
VUE.js实现动态设置输入框disabled属性
Oct 28 Javascript
react quill中图片上传由默认转成base64改成上传到服务器的方法
Oct 30 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/06/18 PHP
WordPress主题中添加文章列表页页码导航的PHP代码实例
2015/12/22 PHP
Laravel find in set排序实例
2019/10/09 PHP
jquery 如何动态添加、删除class样式方法介绍
2012/11/07 Javascript
Jquery中children与find之间的区别详细解析
2013/11/29 Javascript
javascript模拟订火车票和退票示例
2014/04/24 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
微信小程序 详解页面跳转与返回并回传数据
2017/02/13 Javascript
angular学习之ngRoute路由机制
2017/04/12 Javascript
vue组件中点击按钮后修改输入框的状态实例代码
2017/04/14 Javascript
vue.js编译时给生成的文件增加版本号
2018/09/17 Javascript
vue打包相关细节整理(小结)
2018/09/28 Javascript
Vue中的情侣属性$dispatch和$broadcast详解
2019/03/07 Javascript
Vue中函数防抖节流的理解及应用实现
2020/04/24 Javascript
JavaScript之scrollTop、scrollHeight、offsetTop、offsetHeight等属性学习笔记
2020/07/15 Javascript
vue使用exif获取图片旋转,压缩的示例代码
2020/12/11 Vue.js
pandas通过索引进行排序的示例
2018/11/16 Python
Transpose 数组行列转置的限制方式
2020/02/11 Python
python 函数中的参数类型
2020/02/11 Python
python环境下安装opencv库的方法
2020/03/05 Python
Python私有属性私有方法应用实例解析
2020/09/15 Python
de Bijenkorf比利时官网:荷兰最知名的百货商店
2017/06/29 全球购物
澳大利亚现代波西米亚风格女装网站:Bohemian Traders
2018/04/16 全球购物
Snapfish爱尔兰:在线照片打印和个性化照片礼品
2018/09/17 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
土木工程专业个人求职信
2013/12/05 职场文书
离婚协议书范本及离婚须知
2014/10/15 职场文书
幼儿园小班教师个人工作总结
2015/02/06 职场文书
个人工作保证书
2015/02/28 职场文书
妈妈再爱我一次观后感
2015/06/08 职场文书
爱的教育观后感
2015/06/17 职场文书
财务人员廉洁自律心得体会
2016/01/13 职场文书
创业计划书之餐饮
2019/09/02 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android
Java字符串逆序方法详情
2022/03/21 Java/Android