首页 > js多层循环的中断问题

js多层循环的中断问题

var a = {
        '1':'1',
        '2':{
            '21':'21',
            '22':'22',
            '23':'23',
            '24':{
                '241':'241',
                '242':'242',
                '243':'243',
                '244':{
                    '2441':'2441',
                    '2442':'2442',
                    '2443':'2443',
                    '2444':'2444',
                },
            },
        },
        '3':'3',
        '4':'4',
        '5':'5',
        '6':'6'
}
///--------------------------------------------------return
function testReturn(a){
    for( p in a){
        console.log(p)
        if( p =='2442' ) return;
        if( typeof a[p] == 'object' ){
            testReturn(a[p]);
        }
    }
}

function testReturn1(a){
    for( p in a){
        var b = a[p];
        console.log(p)

        if( typeof b == 'object' ){
            for( pp in b){
                console.log(pp);
                var c = b[pp];

                if(typeof c == 'object' ){
                    for( ppp in c){
                        console.log(ppp);
                        var d = c[ppp];

                        if(typeof d == 'object' ){
                            for( pppp in d){
                                console.log(pppp)
                                if(pppp == '2442') return;
                            }
                        }
                    }
                }


            }
        }
    }
}

console.log('--return--')
testReturn(a)
console.log('--return1--')
testReturn1(a)

--return-- 
1
2 
21
22 
23 
24 
241
242
243 
244
2441 
2442 
3 
4 
5
6 
--return1-- 
1 
2 
21 
22
23
24 
241 
242 
243 
244 
2441 
2442 

return中断多层循环的时候,用递归和直接循环,结果不同。

同样的条件用continue、break中断,却能得到一致的结果。

也就是说只有在直接循环且return中断的条件下,是跳出所有循环的,其他情况都留有最初的一层循环,怎么解释上述情况的不同。

1
2 
21
22 
23 
24 
241
242
243 
244
2441 
2442 
3 
4 
5
6 

递归的每一层都是一次函数调用,也就是说,在你遍历到a的最内层的时候
此时的调用栈是

#main
|- testReturn(a)
   |- testReturn(a['2'])
      |- testReturn(a['2']['24'])
         |- testReturn(a['2']['24']['244'])

在最内层执行 testReturn(a['2']['24']['244'])的时候,遇到了return语句,将会跳出当前执行的函数,返回上层主调函数继续执行下一句,直到上层函数执行完毕,返回再上一层继续执行

而使用嵌套for循环的方式,只有一个函数

#main
|- testReturn1(a)

一旦return,将会忽略所有正在执行的循环,直接跳出,返回到主函数逻辑中

而为什么用break continue 实现的效果是一样的?

因为break continue的作用效果是针对当前最内层的循环,也就是无论是递归还是for嵌套的方式,break都只会跳出最内层的循环

那怎么不通过returnbreak也能跳出最外层的循环呢?需要加上label

function testReturn1(a){

    loop1: // attention here
    for( p in a){
        var b = a[p];
        console.log(p)
        if( typeof b == 'object' ){

            loop2:
            for( pp in b){
                console.log(pp);
                var c = b[pp];
                if(typeof c == 'object' ){

                    loop3:
                    for( ppp in c){
                        console.log(ppp);
                        var d = c[ppp];
                        if(typeof d == 'object' ){

                            loop4:
                            for( pppp in d){
                                console.log(pppp)
                                if(pppp == '2442')
                                    break loop1; // attention here
                            }
                        }
                    }
                }
            }
        }
    }
}

你可以在想跳出的循环前面加上一个label,然后在控制语句break或者continue后面跟上这个标签,表示跳出/继续这一层的循环


return是返回到函数的调用处,所以,当你使用递归的方法运行的时候,执行到p == 2442的时候,会逐层向上返回,一直返回到数据的最外层,然后输出剩下的3, 4, 5, 6

但是第二种方法就不一样了,只有一个调用处,当执行到p == 2442的时候直接返回到调用处了,也就是退出了,所以剩下的3, 4, 5, 6也就没有输出。

【热门文章】
【热门文章】