一、概念
在程序中函数直接或间接调用自己。
注意一点,递归需要一个 边界条件来打断递归。要不然的话会进入死循环
二、案例
1、阶乘的例子
function fact(num) {
if (num <= 1) {
return 1;
} else {
return num * fact(num - 1);
}
}
fact(3) // 结果为 6
以下代码可导致出错:由于fact已经不是函数了,所以出错。
var anotherFact = fact;
fact = null;
alert(antherFact(4)); //出错
解决方法:使用arguments.callee
arguments.callee 是一个指向正在执行的函数的指针,arguments.callee 返回正在被执行的对象。
function fact(num){
if (num<=1){
return 1;
}else{
return num*arguments.callee(num-1); //此处更改了。
}
}
var anotherFact = fact;
fact = null;
alert(antherFact(4)); //结果为24.
补充:利用阶乘实现 斐波那契数列
// 斐波那契函数 f(n) = f(n-1) + f(n-2)
function febonacci(n){
if(n === 0){
return 0
}
if(n === 1){
return 1
}
return febonacci(n-1) + febonacci(n-2)
}
febonacci(10); // 55
2、获取页面上的所有标签
那要从页面上获取标签,不用说我们肯定会想到DOM操作,那获取到了之后呢,我们又不确定某个元素有没有子元素,那怎么办呢,这个时候我们肯定会想到递归
var map = {
};
//采用递归调用的方法,比较方便和简单。
function fds(node) {
if (node.nodeType === 1) {
//这里我们用nodeName属性,直接获取节点的节点名称
var tagName = node.nodeName;
//判断对象中存在不存在同类的节点,若存在则添加,不存在则添加并赋值为1
map[tagName] = map[tagName] ? map[tagName] + 1 : 1;
}
//获取该元素节点的所有子节点
var children = node.childNodes;
for (var i = 0; i < children.length; i++) {
//递归调用
fds(children[i])
}
}
fds(document);
console.log(map)
3、多叉树的例子
数据结构格式,参考如下代码:
headerData: {
name: '总数据',
children: [
{
name: '数据1',
children: [
{
name: '数据11',
children: [
{
name: '数据111',
},
{
name: '数据112',
}
]
},
{
name: '数据12',
children: [
{
name: '数据121',
},
{
name: '数据122',
}
]
},
{
name: '数据13',
children: [
{
name: '数据131',
},
{
name: '数据132',
}
]
},
{
name: '数据14',
},
]
}
]
}
叶子结点 就是度为0的结点 就是没有孩子结点的结点,简单的说就是一个二叉树 任意一个分支上的终端节点。
我们如何获取节点的所有叶子节点个数呢? 递归代码如下:
/**
* 获取 节点的所有 叶子节点 个数
* @param {Object} json Object对象
*/
function getLeafCountTree(json) {
if(!json.children){
return 1;
}else{
var leafCount = 0;
for(var i = 0 ; i < json.children.length ; i++){
leafCount = leafCount + getLeafCountTree(json.children[i]);
}
return leafCount;
}
}