Javascript百学不厌-递归

虽然偶尔也用过,但是从来没具体来整理过

普通递归:

function fac(n) {
  if (n === 1) return 1;
  return n * fac(n - 1);
}

fac(5) // 120

这是个阶乘。但是占用内存,因为:

fac(5)

(5*fac(4))

(5*(4*fac(3)))

(5*(4*(3*fac(2))))

(5*(4*(3*(2*fac(1)))))

(5*(4*(3*2)))

(5*(4*(6)))

(5*24)

120

这里需要讲明的是: 函数调用会产生“调用记录(存储着函数的相关信息)”存放在栈中,当有函数返回,对应的调用记录才会消失,

         上述用普通递归实现的阶乘的执行过程中,不断的调用自身,导致一直没有返回,这样也就不断的在栈中存储调用记录

         而当调用自身的次数过多后,就会产生我们常说的“栈溢出”

拟人描述: 就想一个人不断地借钱(调用自身,不断向栈中存调用记录),但是总想着以后再还(一直没有返回),

     当外债积累到超出自己偿还能力的时候,就跑路了(栈溢出)

尾递归

function fac(n, total) {
  if (n === 1) return total;
  return fac(n - 1, n * total);
}

fac(5, 1) // 120

执行过程如下:

fac(5,1)

fac(4,5)

fac(3,20)

fac(2,60)

fac(1,120)

说明:永远只有一个调用记录,调用函数产生一个调用记录,最后一步操作 return fac(n - 1, n * total)

   把当前函数的计算结果当做参数传递给了下一个自身调用,这样第一个函数调用产生的调用记录就消失了,因为它执行完了

   依次类推,就不会溢出

尾递归:函数的最后一步是执行一个函数

参考来自:阮老师

   

         

时间: 2024-10-13 16:35:14

Javascript百学不厌-递归的相关文章

Javascript百学不厌 - 模块模式

记录自己觉得重要又可能忘记的东西 用模块模式产生安全的对象: var serial_maker = function () { var preifx = ''; var seq = 0; return { set_prefix: function (p) { preifx = String(p); }, set_seq: function (s) { seq = s; }, gensym: function () { var result = preifx + seq; seq++; retur

Javascript思学笔记(一)

理论知识点一 一个完整的javascript实现应该由下列三个不同的部分组成1.核心(ECMAScript)2.文档对象模型(DOM)3.浏览器对象模型(BOM) 二.HTML4.01的Script有6个属性,了解一下1.async:表示应该立即下载脚本,但不应妨碍页面中的其他操作,比较下载其他资源或等待加载其他脚本.只对外部脚本文件有效2.charset:代码的字符集.大多数浏览器忽略它的值 ,很少有人用3.defer:表示脚本可以延迟到文档完全被解析和显示之后再执行.4.language:已

总结目前为止JavaScript所学的知识点以及问题

目前为止JavaScript所学的知识点以及问题 第一章: 1.1 JavaScript的应用 1)  通过学习鼠标的事件:onclick(点击事件).onmouseover(鼠标放上).onmouseout(鼠标移走)来操作动画特效. 2)   通过学习JS语法控制页面元素CSS样式. JavaScript 能够直接写入 HTML 输出流中. JavaScript 能够对事件作出反应. JavaScript 能改变 HTML 元素的内容.样式. 1.2 JavaScript的特点 1)    

JavaScript巧学巧用

前言 由于工作和生活上的一些变化,最近写文章的频率有点下降了,实在不好意思,不过相信不久就会慢慢恢复过来,感谢大家一直以来的关注和支持. 本文主要给大家分享一下在编写JavaScript代码的时候存在的一些方法和技巧,虽然有时候条条大路都通向罗马,但是也许总会有那么一条最短的路径可走.希望通过以下几点JavaScript技巧让大家的代码"化繁为简,化简为精". 巧学巧用 1. new Set() 可能有人知道ES6中提供了新的数据结构 Set,但是能够灵活运用的人或许不多.利用Set数

JavaScript语言精粹4递归(汗诺塔游戏寻常解)及作用域

递归函数,就是直接或间接的调用自身的一种函数.把问题,分解成一组相似的子问题,每个问题都用一个一般的方式解决,即寻常解.即函数调用,自身,去解决自身子问题. 经典的递归案例,汗诺塔游戏 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Recursion递归</title> 6 <

Javascript 随学笔记

js变量 js值类型 js运算符: Javascript中的运算符用于算术表达式.比较表达式.逻辑表达式.赋值表达式等. Javascript运算符的优先级从高到低依次为:算术表达式 > 比较表达式 > 逻辑表达式 > 赋值表达式 js语句:条件语句.循环语句 js类型转换 js函数 js递归 js预编译 js作用域 js闭包 js对象 原文地址:https://www.cnblogs.com/zhuwenqin/p/9009870.html

Javascript我学之五对象的创建与使用

本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 对象的创建 JavaScript对象有两种类型 1).Native:在ECMAScript标准中定义和描述,包括JavaScript内置对象(数组,日期对象等)和用户自定义对象. 2).Host:在主机环境(如浏览器)中实现并提供给开发者使用,比如windows对象和所有的DOM对象 对象的含义 Object is an unordered collection of properties each of which contains

Javascript我学之二函数定义

本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘 函数 几个要点: a).函数是javascript中的一等公民 (重要性) b).函数是一个对象 c).函数定义了一个独立的变量作用域 定义方式 a)命名函数:           除非在另一个函数内部定义,否则,命名函数是全局的. 1 // 全局的命名函数 2 function add(x, y) { 3 return x + y; 4 } 5 console.info(add(100, 200)); //300 b)匿名函数: 匿名函

javascript中function 函数递归的陷阱问题

//看下这个递归方法,最后输出的值function fn(i){ i++; if(i<10){ fn(i); } else{ return i; } } var result = fn(0); console.log(result); 大部分人都可能一下就会说出结果为10,但是真实的结果是undefined.为什么呢?因为对于每一个函数,没有写return的返回值的时候,其实对于var a = function(); 就是没有给a赋值,那么这个值就是默认的undefined值了,可以typeof