递归
递归基础知识
递归可以看做函数在运行过程中中,是自己调用自己,如下图所示:
var obj={value:1,next:{value:2,next:{value:3,next:{value:4,next:{value:5,next:null}}}}};
function fn1(obj){
console.log(obj.value);
if(obj.next) fn1(obj.next);
}
fn1(obj);
函数在没有完全执行时,内部的所有变量都不会被销毁。
递归会建立一个函数的副本,在堆中建立相同的函数引用,递归调用时调用这个函数引用。
var i=0;
function fn1(){
var a=3;
i++;
if(i<3) fn2();
console.log(i);//最后打印的
}
function fn2(){
var a=3;
i++;
if(i<3) fn3();
console.log(i);//第二个被打印的
}
function fn3(){
var a=3;
i++;
console.log(i);//最先打印的
}
fn1();
var i=0;
function fn1(){
var a=3;
i++;
if(i<12000) fn1();
console.log(i);//最后打印的
}
fn1();
递归的应用
用于对象的深查找:遍历对象,查找对象中是否有属性值为value的属性,并返回对象的属性
function fn3(o,value){
for(var prop in o){
if(o[prop]===value) return prop;
if(typeof o[prop]==="object" && o[prop]!==null){
var s=fn3(o[prop],value)
if(s) return s;
}
}
}
用于实现对象的深度遍历(也就是深复制):就是对于对象的属性中也是存储的对象类型的元素都遍历,将原对象的属性值都复制给新对象,原对象和新对象的引用关系不相同,只是属性值相同。
function fn1(source,target){
if(target===undefined) target={};
for(var prop in source){
// console.log(prop);
if(typeof source[prop]==="object" && source[prop]!==null){
target[prop]={};
// 如果不加的话,引用关系会发生改变
fn1(source[prop],target[prop])
}
else {
target[prop]=source[prop];
}
}
return target;
}
对象的广度遍历用的是for in语句:语句如下图所示:
function fn1(obj){
for(var prop in obj){
console.log(prop,obj[prop]);
if(typeof obj[prop]==="object" && obj[prop]!==null) fn1(obj[prop])
}
}
fn1(obj);