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 相关文章推荐
ExtJS下grid的一些属性说明
Dec 13 Javascript
javaScript call 函数的用法说明
Apr 09 Javascript
jQuery代码优化 事件委托篇
Nov 01 Javascript
深入理解javascript变量声明
Nov 20 Javascript
jQuery实用技巧必备(上)
Nov 02 Javascript
如何用JavaScript实现动态修改CSS样式表
May 20 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
Jun 08 Javascript
详解webpack和webpack-simple中如何引入css文件
Jun 28 Javascript
JavaScript实现图片无缝滚动效果
Jul 07 Javascript
js实现以最简单的方式将数组元素添加到对象中的方法
Dec 20 Javascript
利用Decorator如何控制Koa路由详解
Jun 26 Javascript
微信小程序云开发如何实现数据库自动备份实现
Aug 16 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 curl请求信息和返回信息设置代码实例
2015/04/27 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
PHP递归遍历指定文件夹内的文件实现方法
2016/11/15 PHP
屏蔽F1~F12的快捷键的js函数
2010/05/06 Javascript
jquery 结合C#后台的数组对文章的关键字自动添加链接的代码
2011/07/15 Javascript
自己动手开发jQuery插件教程
2011/08/25 Javascript
js汉字排序问题 支持中英文混排,兼容各浏览器,包括CHROME
2011/12/20 Javascript
js或者jquery判断图片是否加载完成实现代码
2013/03/20 Javascript
js判断屏幕分辨率的代码
2013/07/16 Javascript
jQuery.lazyload+masonry改良图片瀑布流代码
2014/06/20 Javascript
JavaScript动态添加style节点的方法
2015/06/09 Javascript
Jquery实现的简单轮播效果【附实例】
2016/04/19 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
AjaxUpLoad.js实现文件上传功能
2018/03/02 Javascript
vue-router 源码实现前端路由的两种方式
2018/07/02 Javascript
jquery登录的异步验证操作示例
2019/05/09 jQuery
如何使用JavaScript检测空闲的浏览器选项卡
2020/05/28 Javascript
[16:19]教你分分钟做大人——风暴之灵
2015/03/11 DOTA
python使用cPickle模块序列化实例
2014/09/25 Python
Python中的模块和包概念介绍
2015/04/13 Python
Python制作钉钉加密/解密工具
2016/12/07 Python
浅谈Python 的枚举 Enum
2017/06/12 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
2018/08/22 Python
简单了解Pandas缺失值处理方法
2019/11/16 Python
解决python -m pip install --upgrade pip 升级不成功问题
2020/03/05 Python
在服务器上安装python3.8.2环境的教程详解
2020/04/26 Python
详解Python遍历列表时删除元素的正确做法
2021/01/07 Python
花卉与景观设计系大学生求职信
2013/10/01 职场文书
学习党章思想汇报
2014/01/07 职场文书
大学生如何写自荐信
2014/01/08 职场文书
生产文员岗位职责
2014/04/05 职场文书
2015年秘书个人工作总结
2015/04/25 职场文书
员工表扬信怎么写
2015/05/05 职场文书
2016应届毕业生自荐信范文
2016/01/28 职场文书
《烈火英雄》观后感:致敬和平时代的英雄
2019/11/11 职场文书
浅谈GO中的Channel以及死锁的造成
2022/03/18 Golang