如何打破递归函数内的 for 循环并在 Javascript 中返回?

Posted

技术标签:

【中文标题】如何打破递归函数内的 for 循环并在 Javascript 中返回?【英文标题】:How to break out of a for loop inside a recursive function and return in Javascript? 【发布时间】:2013-01-31 02:57:27 【问题描述】:

我正在尝试比较两个对象的键,属性值无关紧要。

var obj1 = 
    foo: 
        abc: "foo.abc",
    ,
    bar: 
        aaa: 
            bbb: "bar.aaa.bbb" // <-- difference
        
    
;

var obj2 = 
    foo: 
        abc: "foo.abc",
    ,
    bar: 
        aaa: 
            ccc: "bar.aaa.ccc" // <-- difference
        
    
;
// function should return true if properties are identical, false otherwise
function compareObjProps(obj1, obj2) 
    for(var prop in obj1) 

        // when comparing bar.aaa.bbb and bar.aaa.ccc
        // this does get logged, but the function doesn't return false
        if(!obj2.hasOwnProperty(prop)) 
            console.log("mismatch found");
            return false;
        

        if(typeof(obj1[prop]) === "object") 
            compareObjProps(obj1[prop], obj2[prop]);
        
    

    // this always returns
    return true;

看来return false不是从顶层函数返回的,而是递归的。

那么当整个匹配函数执行完毕后如何返回false呢?

【问题讨论】:

你怎么知道它没有返回false?你评估返回值吗? @MeNoMore var result = compareObjPros(obj1, obj2); console.log(result); 总是正确的... 【参考方案1】:

你错过了回报:

    if(typeof(obj1[prop]) === "object"
        && !compareObjProps(obj1[prop], obj2[prop]))
    
       return false;
    

否则递归调用的结果将被完全忽略。

【讨论】:

我认为你的意思是当递归调用返回 false 时返回应该发生(见编辑)...... @AlexeiLevenkov:是的。我实际上是在考虑路径而不是属性树。感谢您的编辑。 不...您的第一个或编辑的版本都没有返回错误。还是真的……我做错了什么吗?【参考方案2】:

是的,函数 B 调用的函数 A 不能告诉 B 返回。有些人建议返回递归调用的结果,但这不会给你正确的结果,因为它会导致程序返回它找到的第一个子对象是否相同,而不是如果所有对象都相同.我建议您进行此修改:

if(typeof(obj1[prop]) === "object") 
   if(!compareObjProps(obj1[prop], obj2[prop]))
      return false;
   

这将使您的程序根据需要传播“假”,但如果结果为“真”,则使其继续运行。

【讨论】:

嘿嘿嘿...谁对这个答案投了反对票?解释中可能有一些不恰当的地方。但它确实有效的代码!【参考方案3】:

试试这个:

function compareObjProps(obj1, obj2) 
    var result = true;
    for (var prop in obj1) 
        if (obj1.hasOwnProperty(prop) && !obj2.hasOwnProperty(prop)) 
            console.log("mismatch found");
            result = false;
         else if (typeof(obj1[prop]) === "object") 
            result = compareObjProps(obj1[prop], obj2[prop]);
        

        if (!result) 
            break;
        
    

    return result;

http://jsfiddle.net/gSYfy/4/

【讨论】:

那行得通。我通过添加一个变量来跟踪结果来做同样的事情,但没有成功。谢谢兰。 @user1643156 太棒了,很高兴它的工作/帮助。确保您对其进行测试以验证它是否可以正常工作,尽管它看起来不错。如果您遇到任何事情,请告诉我! 对不起 lan 但我不得不接受 Zeta 的回答,因为它不需要额外的变量。无论如何,谢谢。 @user1643156 没问题。如果您想扩展此递归以做更多事情,我不确定这是否是一个好的解决方案,但只要您有工作要做,那就太好了!

以上是关于如何打破递归函数内的 for 循环并在 Javascript 中返回?的主要内容,如果未能解决你的问题,请参考以下文章

运行递归查询时如何打破雪花中的循环

如何打破 C 中的无限 for(;;) 循环?

如何打破 Objective-C 中的两个嵌套 for 循环?

如何在python的内部for循环中打破while循环?

python语言如何结尾?

递归 C# 函数从 for 循环内部返回 - 如何转换为 F#?