今天在开发中遇到一个递归方面的错误,修改了好多遍才发现自己对于递归返回上的认识错误。一共发现两个问题,先说第一个,返回值的问题,上问题代码
1 var value=[1,2,3,4,5,6]; 2 var result=[]; 3 var i; 4 function find(i){ 5 if(i<4){ 6 result[i]=value[i] 7 find(i+1); 8 } 9 else 10 return result; 11 } 12 find(0);
这段代码返回为undefined,原因在于返回值没有弄清楚,首先,我们调用的是find(0),而find(0)是没有返回值的,注意那个return result并不是find(0)的返回值,那只是if语句条件不满足之后的返回语句,在f(0)中我们并没有进入else分支,你调用find(0),它继续调用find(1),然后依此调用,然后条件不满足了,语句结束,注意递归的find(4)并不会进入到else分支!!它只是使得if{}中不再调用!!!所以并没有return!而在find(0)语句调用中我们同样也没有返回值,所以才会出现undefined的情况,同样,我们可以这样修改代码:
1 var value=[1,2,3,4,5,6];
2 var result=[];
3 var i;
4 function find(i){
5 if(i<4){
6 result[i]=value[i]
7 find(i+1);
return result;
8 }
9 else
10 return result;
11 }
12 find(0);
这样在调用完了return,是find(0)没有返回result,而我们需要的是find(4)的return result,所以我们在if{}中加一个return,返回的是调用完了result,递推的return是最后一次调用的returnt,修改代码为:
1 var value=[1,2,3,4,5,6]; 2 var result=[]; 3 var i; 4 function find(i){ 5 if(i<4){ 6 result[i]=value[i]; 7 return result; 8 find(i+1); 9 10 } 11 else 12 return result; 13 } 14 find(0);
这样只返回1,因为只调用了一次就返回了,函数随即停止,而上一种改法,要等所有的调用完成才返回。
我们可以再次修改,来佐证我们关于返回的看法:
1 var value=[1,2,3,4,5,6]; 2 var result=[]; 3 var i; 4 function find(i){ 5 if(i<4){ 6 result[i]=value[i]; 7 find(i+1); 8 9 } 10 else; 11 return result; 12 } 13 find(0);
我们看到,我们在else后面加了一个空语句,那这样,find(0)就有返回了,返回调用完成之后的result值。
还有一个错误是,如果我们这样来写代码:
var value=[1,2,3,4,5,6]; var result=[]; var i; function find(i){ if(i<4){ result[i]=value[i]; find(i+1); } else; return result[i]; } find(0);
我们发现也是返回undefined,这里我们误解了一个很重要的一点,这里的i是参数而不是计数的i,它是形参赋值之后就没有了,所以我们不能用result[i],那样会恒返回result[0]而对于这样两个错误综合起来的写法
1 var value=[1,2,3,4,5,6]; 2 var result=[]; 3 var i; 4 function find(i){ 5 if(i<4){ 6 result[i]=value[i] 7 find(i+1); 8 } 9 else 10 return result[i]; 11 } 12 find(0);
则会返回undefined,因为首先if本身执行完了就是没有返回值的,再者即便return 也只能return result[0]