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

for循环 JavaScript

C.C女王受 10 years, 1 month ago

递归 的每一层都是一次 函数调用 ,也就是说,在你遍历到 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 都只会跳出 最内层的循环

那怎么不通过 return break 也能跳出最外层的循环呢?需要加上 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 后面跟上这个标签,表示 跳出/继续 这一层的循环

单翼的鸡翅膀 answered 10 years, 1 month ago

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

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

Gakaduo answered 10 years, 1 month ago

Your Answer