2013-02-15 41 views
2

我想比較兩個對象的鍵,屬性的值並不重要。如何擺脫遞歸函數內的for循環並返回Javascript?

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?

+0

你怎麼知道它diesn't返回false?你評估回報價值嗎? – CloudyMarble 2013-02-15 06:45:40

+0

@MeNoMore'var result = compareObjPros(obj1,obj2); console.log(result);'始終爲真... – user1643156 2013-02-15 06:50:22

回答

4

你錯過一回:

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

否則遞歸調用的結果都將被完全忽略。

+0

我認爲你的意思是說,遞歸調用返回false時會發生返回錯誤(請參閱編輯)... – 2013-02-15 06:46:59

+0

@AlexeiLevenkov:是的。我實際上是在思考道路而不是屬性樹。感謝編輯。 – Zeta 2013-02-15 06:47:33

+0

不......你的第一個或編輯過的版本都不會返回false。真的還是......我做錯了什麼? – user1643156 2013-02-15 06:49:14

0

是的,函數B調用的函數A不能告訴B返回。有些人建議返回遞歸調用的結果,但這不會給你正確的結果,因爲它會導致程序返回它找到的第一個子對象是否相同,而不是所有對象是否相同。我建議你做此修改:

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

這會讓你的程序傳播「虛假的」,你想要的,但讓它繼續下去,如果結果爲「真」。

+1

HEYHEYHEY ......誰回答了這個問題?解釋中可能有不妥之處。但它的工作代碼! – user1643156 2013-02-15 07:05:42

2

試試這個:

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/

+0

工作。我通過添加一個變量來跟蹤結果,但是沒有成功。謝謝你。 – user1643156 2013-02-15 06:57:23

+0

@ user1643156真棒,很高興它的工作/幫助。確保你測試它來驗證它完全工作,雖然看起來不錯。如果您遇到任何問題,請告訴我! – Ian 2013-02-15 06:59:57

+0

對不起,但我不得不接受Zeta的答案,因爲它不需要額外的變量。不管怎麼說,還是要謝謝你。 – user1643156 2013-02-15 07:22:14