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.messager.js插件导致页面抖动的解决方法
Jul 14 Javascript
我用的一些Node.js开发工具、开发包、框架等总结
Sep 25 Javascript
JavaScript+CSS实现仿天猫侧边网页菜单效果
Aug 25 Javascript
JQuery标签页效果的两个实例讲解(4)
Sep 17 Javascript
jQuery Uploadify 上传插件出现Http Error 302 错误的解决办法
Dec 12 Javascript
javascript实现下雪效果【实例代码】
May 03 Javascript
原生js实现网易轮播图效果
Apr 10 Javascript
基于BootstrapValidator的Form表单验证(24)
Dec 12 Javascript
详解Vue中使用v-for语句抛出错误的解决方案
May 04 Javascript
vue2中的keep-alive使用总结及注意事项
Dec 21 Javascript
js+canvas实现验证码功能
Sep 21 Javascript
微信小程序功能之全屏滚动效果的实现代码
Nov 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
简单介绍下 PHP5 中引入的 MYSQLI的用途
2007/03/19 PHP
php运行出现Call to undefined function curl_init()的解决方法
2010/11/02 PHP
php共享内存段示例分享
2014/01/20 PHP
让codeigniter与swfupload整合的最佳解决方案
2014/06/12 PHP
php实现的一段简单概率相关代码
2016/05/30 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
Yii2框架redis基本应用示例
2018/07/13 PHP
js获取变量
2006/08/24 Javascript
用Javascript评估用户输入密码的强度实现代码
2011/11/30 Javascript
EasyUi datagrid 实现表格分页
2015/02/10 Javascript
JS点击链接后慢慢展开隐藏着图片的方法
2015/02/17 Javascript
JavaScript中Function详解
2015/02/27 Javascript
AngularJS中一般函数参数传递用法分析
2016/11/22 Javascript
实例浅析js的this
2016/12/11 Javascript
JS获取浏览器地址栏的多个参数值的任意值实例代码
2018/07/24 Javascript
Puppet的一些技巧
2018/09/17 Javascript
js replace替换字符串同时替换多个方法
2018/11/27 Javascript
jQuery实现简单评论区功能
2020/10/26 jQuery
[02:35]DOTA2英雄基础教程 末日使者
2013/12/04 DOTA
[35:34]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python的Flask框架中SQLAlchemy使用时的乱码问题解决
2015/11/07 Python
关于numpy中np.nonzero()函数用法的详解
2017/02/07 Python
Python中查看文件名和文件路径
2017/03/31 Python
python实现批量注册网站用户的示例
2019/02/22 Python
python银行系统实现源码
2019/10/25 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
css3强大的动画效果animate使用说明及浏览器兼容介绍
2013/01/09 HTML / CSS
html5菜单折纸效果
2014/04/22 HTML / CSS
农行实习自我鉴定
2013/09/22 职场文书
学院书画协会部门岗位职责
2013/12/01 职场文书
小学语文国培感言
2014/03/04 职场文书
社区网格化管理实施方案
2014/03/21 职场文书
2014年法务工作总结
2014/12/11 职场文书
2015年安全生产工作总结范文
2015/04/02 职场文书
商务宴会祝酒词
2015/08/11 职场文书
关于使用Redisson订阅数问题
2022/01/18 Redis