递归一般用于树的遍历、对象深拷贝、无限分层菜单等用途,然而这个东西理解起来真的很别扭,这里写出一个自己的理解方式。
以一个递归生成包含从1到2的数组函数为例:
function digui( i ){
var arr = []
i++
if( i < 3){
arr.push(i)
arr = arr.concat( digui(i) )
}
return arr
}
console.log(digui(0))
说一下运行过程:
首先传入参数0,运行digui(0)
:
判断1<3,arr.push(1)
,所以当前arr是[1]
继续执行:[1].concat(运行digui(1),必须等待digui(1)返回结果才能继续运行)
开始执行digui(1)
:
判断2<3,arr.push(2)
,当前arr是[2]
继续执行:[2].concat(运行digui(2),必须等待digui(2)返回结果才能继续运行)
判断3 == 3,所以运行return arr
,arr是[],到此最内层递归结束,开始向上回溯
计算[2].concat([])
,并把结果赋值给arr,arr当前是[2],返回arr,供上一层递归使用,本层结束
计算[1].concat([2])
,并把结果赋值给arr,arr当前是[1, 2],返回arr,没有上一层了,函数运行结束
可以看出递归的效果是从最内层开始向外返回值
比如这个方法:
function dg(i){
i++
if(i < 3){
dg(i)
}
console.log(i)
return i
}
dg(0) // 3 2 1
是按照3->2->1的顺序打印的,而不是1->2->3;
最后来个实用点的,深拷贝对象:
function deepClone(obj){
var temp = {};
for(var key in obj){
if(obj.hasOwnProperty(key)){
temp[key] = typeof obj[key] === "object" ? deepClone(obj[key]) : obj[key];
}
}
return temp;
}