所谓的递归函数,就是函数在自己的内部再次调用自己。
来看一个简单的入手例子:
<script>
var i=0;
function funny(){
if(i<6){ //1
i++; //2
console.log(i); //3
funny(); //4
console.log(i); //5
}
}
</script>
照以前错误的思维:
funny()内部的函数调用自己6次,当第6次调用自己的时候,i=6不满足if条件,跳出循环,继续执行第五行,只执行一次,所以打印的结果应该是:1 2 3 4 5 6 6。
然而结果是:1 2 3 4 5 6 6 6 6 6 6 6。
说明后来console.log第五行执行了6次,而不是一次。
原因:函数每调用一个函数,就将进入新的执行环境,这个执行环境被保存在栈中,根据栈的先进后出原则,老函数会被压在最下面,当新函数完成时被弹出栈,执行环境返回到老函数,老函数从调用新函数的下一行继续执行代码,自己的代码执行完毕,自己的执行环境也被弹出栈(销毁),执行环境又返回到调用它的那个函数中.......
在funny6()被调用完毕时,console.log(6),然后funny6()被弹出栈,则进入funny5()执行环境,进行下一条语句的执行console.log(i),因为i是全局变量,最后一次i++使得i=6,所以打印结果是6;然后funny5()最后一条语句也执行完毕,被弹出栈,进入funny4()第四层执行环境,以此类推。因为最后i=6,不再改变,所以最后打印出来的都是666666.
有了这个基础,再看一个例子:
function BinarySearchTree() {
var Node = function(key){
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
} //到这里是创建一个二叉搜索树的类;
var inOrderTraverseNode = function (node, callback) { //1
if (node !== null) { //2
inOrderTraverseNode(node.left, callback); //3
callback(node.key); //4
inOrderTraverseNode(node.right, callback); //5
} };
function callback(value){
console.log(value);
}
代码段的第三行 用left表示,第四行用right表示;
进入函数后执行left第一层函数,if条件通过,进入函数执行left第二层函数,if条件通过,又进入函数执行left第3层函数,if条件通过,又进入函数执行left第4层函数,妄图进入函数的第五层,发现left为null, if条件不通过,
返回第四层,开始顺序执行callback()函数打印3,然后又顺序执行right妄图进入函数的第五层, 发现right为null, if条件不通过,返回树的第四层。第四层执行完毕。
返回第三层,开始顺序执行callback()函数打印5,然后又顺序执行right,if条件通过,进入函数的第四层,然后又顺序执行left妄图进入第五层, if条件不通过,返回树的第四层,然后又顺序执行callback()函数打印6,然后又顺序执行函数right妄图进入函数五,if条件不通过,返回第四层,第四层执行完毕,返回第三层,第三层执行完毕,
返回第二层。。。。你懂的。
以此类推:最后打印出来的结果是:3 5 6 7 8 9 10 11 12 13 14 15 18 20 25
这递归看的头晕。