Functional-Light-JS ---- Recursion

recursion.js 简易的三层迭代方式,放入parent,可format出三层分类。 立即下载

递归

  1. 递归的定义
  2. 递归的好处
  3. 互递归
  4. 递归的弊端
  5. 尾调用
  6. 递归的优化
递归的定义

递归就是一个函数在其内部调用它自己,同时有一个条件来终止这个递归的循环调用。

递归的好处

递归可以使我们的代码更加的接近声明式的代码,可读性会更加好一些。

	The most commonly cited reason that recursion fits the spirit of FP is because it trades (much of) 
	the explicit tracking of state with implicit state on the call stack. Typically, recursion is most useful
	when the problem requires conditional branching and back-tracking, and managing that kind
	of state in a purely iterative environment can be quite tricky; at a minimum, the code is highly 
	imperative and harder to read and verify. But  tracking each level of branching as its own scope 
	on the call stack often significantly cleans up the readability of the code.
互递归

互递归(Mutual Rescursion)就是当两个或多个函数在递归循环中相互调用时,这称为互递归。
example:

	function isOdd(v) {
	    if (v === 0) return false;
	    return isEven( Math.abs( v ) - 1 );
	}
	
	function isEven(v) {
	    if (v === 0) return true;
	    return isOdd( Math.abs( v ) - 1 );
	}
递归的弊端

递归可能导致堆(stack)内存泄露。

尾调用

当函数的最后一步是函数调用时,我们称之为尾调用(tail call)。在ES6中有个一针对尾调用的概念,叫PTC(Proper Tail Calls)即合适的尾调用,JS引擎会针对这种调用进行优化。ES6中的尾递归优化还有一个重要前提,就是必须在严格模式下才可以。还有一个概念叫尾调用优化,英文原文是Tail Call Optimizations (TCO)。

//These are not PTC:
foo();
return;

// or
var x = foo( .. );
return x;

// or
return 1 + foo( .. );

//PTC
return x ? foo( .. ) : bar( .. );
递归的优化
  1. 将递归转换为尾调用优化的形式
    这种优化很好理解,就是在可能的情况下,将我们的函数转换为尾调用的形式。

  2. 使用蹦床函数
    蹦床(Trampolines)函数的本质就是只要返回一个函数,循环就会继续,执行该函数并捕获它的返回,然后检查它的类型。一旦非函数返回,蹦床就假定函数调用已经完成,并返回值。

    function trampoline(fn) {
        return function trampolined(...args) {
            var result = fn( ...args );
    
            while (typeof result == "function") {
                result = result();
            }
    
            return result;
        };
    }
    
    var sum = trampoline(
        function sum(num1,num2,...nums) {
            num1 = num1 + num2;
            if (nums.length == 0) return num1;
            return () => sum( num1, ...nums );
        }
    );
    
    var xs = [];
    for (let i=0; i<20000; i++) {
        xs.push( i );
    }
    
    sum( ...xs );                   // 199990000
    

    使用蹦床函数可以可以调出尾递归优化的限定,运行也很快

  3. 使用连续传递函数的形式
    连续传递函数(Continuation Passing Style),这个优化的本质还是使用了尾调用优化。组织代码,使每个函数接收另一个函数在其末尾执行,这称为延续传递样式(CPS)。
    这是一个针对fibco数列的递归优化示例:

    "use strict";
    
    function fib(n,cont = identity) {
        if (n <= 1) return cont( n );
        return fib(
            n - 2,
            n2 => fib(
                n - 1,
                n1 => cont( n2 + n1 )
            )
        );
    }
    

    我个人觉得这是相当晦涩难懂的。。。

hadoop 切片机制详解 hadoop切片机制详解 阅读详情

相关推荐

粒子滤波在基于误差状态量的INS/GNSS组合导航中的使用技巧-On Particle Filter based Error-State INS/GNSS Intergrated Navigation

本文面向以15维惯导(INS)误差为状态量,3维位置误差为量测量的INS/GNSS组合导航系统,​在西工大严恭敏老师的开源工具箱中PF相关库函数基础上实现基于粒子滤波(PF)的惯导误差状态量的递推估计,设计了粒子重置环节并强调了其在本特定场景下的重要性。

I33D33I的博客 1742

Functional-Light-JS 摘录笔记(1)

function foo(...args) { console.log( args[3] ); } var arr = [ 1, 2, 3, 4, 5 ]; foo( ...arr ); // 4 Think of...in this symmetric sense: in a value-list positio...

weixin_30287169的博客 202

24位ADC的精度陷阱:为什么你的ADS1232实测性能不达标?

本文深入探讨了24位ADC芯片ADS1232在实际应用中性能不达标的原因,揭示了高精度ADC性能依赖周边电路设计的关键问题。通过分析电源系统、参考电压稳定性、PCB布局等常见陷阱,提供了优化方案和调试技巧,帮助工程师充分发挥ADS1232的潜力,实现接近理论值的测量精度。

weixin_28285943的博客 406

全本 | iKcamp翻译 | 《JavaScript 轻量级函数式编程》|《你不知道的JS》姊妹篇

原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 译者团队(排名不分先后):阿希、blueken、brucecham、cfanlife、dail、kyoko-df、l3ve、lilins、LittlePineapple、MatildaJin、冬青、pobusama、Cherry、萝卜、vavd317、vivax...

weixin_33947521的博客 364

保姆级教程:用再生龙Clonezilla Live给Ubuntu系统做全盘备份与恢复(含BIOS设置避坑)

本文提供了一份详细的Clonezilla Live教程,指导Ubuntu用户如何轻松完成全盘备份与恢复。从启动盘制作、BIOS设置避坑到备份参数解析和恢复操作,涵盖了所有关键步骤和常见问题解决方案,帮助用户高效保护系统数据。

weixin_42116058的博客 641

C#报表,使用微软rdlc模板,生成Excel, PDF, Word, Image文件,使用自定义对象做数据集不连接数据库

我项目是用vs2017 建的,.NET farmwork 4.7.2 这种报表可以用于任何模式的应用,web,桌面,因为这只是生成一个文件或者文件流 步骤比较详细啰嗦,其中有讲到rdlc怎么新建设计,如果已经会设计rdlc了的可以直接跳到底部看代码的执行结果, 底部还有源码下载链接,百度盘 首先控制台安装报表包 新建rdlc 报表 建立rdlc里要用的数据模型 模型建完,或者修改都要重新...

qq_35955916的博客 5203

翻译连载 | JavaScript轻量级函数式编程-第4章:组合函数 |《你不知道的JS》姊妹篇...

原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱;分享,是 CSS 里最闪耀的一瞥;总结,是 JavaScript 中最严谨的逻辑。经过捶打磨练,成就了本书的中文版。本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走...

weixin_34162695的博客 305

AI上推荐 之 NeuralCF与PNN模型(改变特征交叉方式)

1. 前言 随着信息技术和互联网的发展, 我们已经步入了一个信息过载的时代,这个时代,无论是信息消费者还是信息生产者都遇到了很大的挑战: 信息消费者:如何从大量的信息中找到自己感兴趣的信息? 信息生产者:如何让自己生产的信息脱颖而出, 受到广大用户的关注? 为了解决这个矛盾, 推荐系统应时而生, 并飞速前进,在用户和信息之间架起了一道桥梁,一方面帮助用户发现对自己有价值的信息, 一方面让信息能够展现在对它感兴趣的用户前面。 推荐系统近几年有了深度学习的助推发展之势迅猛, 从前深度学习的传统推荐模型(协

Miracle8070 1万+

翻译连载 | JavaScript 轻量级函数式编程-第1章:为什么使用函数式编程?|《你不知道的JS》姊妹篇 ...

原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱;分享,是 CSS 里最闪耀的一瞥;总结,是 JavaScript 中最严谨的逻辑。经过捶打磨练,成就了本书的中文版。本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路...

weixin_33941350的博客 355

ardupilot 获取避障传感器数据

本节主要记录自己学ardupilot的避障代码过程,首先看下怎么注册避障传感器,然后怎么获取避障数据。

陌城烟雨 5524

Android Framework AMS面试题及参考答案

比如,应用 B 的 Activity 如果是 “singleTask” 启动模式,AMS 会查找应用 B 是否有包含该 Activity 的任务栈,若有则将这个任务栈切换到前台,并且清除该 Activity 之上的其他 Activity,实现流畅的跨应用跳转体验。如果一个 Activity 的启动依赖于另一个 Activity 的结果,AMS 会暂停当前 Activity 的部分生命周期操作,等待依赖的 Activity 完成相关操作后,再继续当前 Activity 的生命周期进程。

大模型大数据攻城狮的专栏 1858

前端学习心得-javascript设计模式与开发实践-高阶函数

高阶函数(满足至少一点): 1、函数可以作为参数被传递 常用于做回调函数,用于分离业务逻辑中容易变化的部分 2、函数可以作为返回值输出 让函数在执行完后继续返回一个可执行函数 类型判断 普通方法,创建一个对象,把每种对象的判断方法作为属性依次写入 isType = { isString: function(obj){ return Object.prot

qq_32705043的博客 298

2026软考中级-软件设计师笔记(送最新视频教程)

核心口诀:运控存输输(运算器、控制器、存储器、输入、输出)例题(2019年上半年):核心公式:数字签名流程:数字证书作用:死锁4个必要条件:死锁判断公式:处理策略:程序设计语言的四大核心成分:顺序表操作(时间复杂度):链表操作(时间复杂度):核心思想:频率高的字符用短编码,频率低的用长编码 → 最小化总编码长度构造步骤(贪心算法):前提:有序表(升序/降序) 步骤:时间复杂度:O(log₂n) 例:查找中核心思想:用哈希函数将关键字映射到存储位置 哈希冲突:不同关键字映射到同一位置 → 用链地址法或开放定址

36万+

翻译连载 | JavaScript 轻量级函数式编程-第2章:函数基础 |《你不知道的JS》姊妹篇 ...

原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱;分享,是 CSS 里最闪耀的一瞥;总结,是 JavaScript 中最严谨的逻辑。经过捶打磨练,成就了本书的中文版。本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路...

weixin_33753003的博客 287

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

js中递归函数的使用

 &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;me

Cool的博客 1034

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

javascript 递归函数调用(recursive funciton call)

所谓的递归函数调用,就是自己调用自己的函数。 1 var timerHandler = null; 2 function a(){ 3 console.log(123); 4 timerHandler = setTimeout(a, 1000) ; 5 } 6 a(); 7 //clearTimeout(timerHandler);   -----------------...

weixin_33804582的博客 614

翻译连载 | 附录 A:Transducing(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇...

原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱;分享,是 CSS 里最闪耀的一瞥;总结,是 JavaScript 中最严谨的逻辑。经过捶打磨练,成就了本书的中文版。本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走...

weixin_34228387的博客 198

保姆级教程:用Hi3519AV200和Hi3403 SDK从零搭建你的第一个IPC摄像头(附固件烧录避坑指南)

本教程详细介绍了如何使用海思Hi3519AV200和Hi3403 SDK从零搭建IPC摄像头,涵盖硬件选型、SDK环境搭建、固件烧录及MPP编解码等关键步骤。特别提供了Hi3519AV200与Hi3403的核心参数对比和烧录避坑指南,适合嵌入式开发初学者快速上手智能摄像头开发。

weixin_33728268的博客 355

eslint提示'React' is defined but never used

使用eslint --init进行基础的设置后,在React项目中发现如下报错提示 'React' is defined but never used 在.eslintrc.js文件中配置如下rule即可 "react/jsx-uses-react": 2

izwell的博客 8235

ESLINT错误提示 no-unused-vars

ESLINT错误提示 no-unused-vars 使用ESLINT时遇到如下错误的提示 查阅资料得知,是需要使用插件 https://github.com/typescript-eslint/typescript-eslint/issues/941 全局按照 eslint-plugin-react npm install eslint-plugin-react -g 修改eslint的配置项...

izwell的博客 8123

JS数组去重

JS数组去重 最近看了下关于数组去重相关的方法,现在自己做一下总结。 情境 输入 [1,1,‘true’,‘true’,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN’, 0, 0, ‘a’, ‘a’,{},{}]; 输出 过滤掉数组中重复的值 ES6-set 使用ES6中的set是最简单...

izwell的博客 5993

JS正则实现数值千分位

今天在看vuex的demo时,看到引用了一个currency脚本文件,通过仔细分析其中的代码,发现其主要作用就是进行数值千分位的处理。现简要梳理一下从这个脚本中学习吸收到的东西。 场景: 进行js中数字的整数部分千分位划分 input:1234.56478 output:1,234.5678 先说说大体的实现思路,先将该数字转换成字符串,获取整数部分,...

izwell的博客 5990

JS中创建任意长度的填充数组

JS中创建任意长度的填充数组 常见的创建数组的方式就是使用Array(length);这种方式来创建数组,但这样创建的数组会存在两个问题, 一是所生成的数组实际上是一个稀疏数组。而由此所带来的直接问题是,你无法使用map或者forEach方法来对其进行遍历。 举个列子 var a = new Array(5); //[,,,,] a = a.map((item, index)=>index)...

izwell的博客 4932
上一篇: JS中创建任意长度的填充数组
下一篇: ESLINT错误提示 no-unused-vars
izwell
博客等级 码龄14年 16粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值