2016-07-30 54 views
0

我正在從Eloquent Javascript書中學習Javascript。我在我的代碼的深層次比較運動在第4章是如何失敗的(介紹對象)深入的比較(雄辯的Javascript第4章):代碼未通過測試用例

目標

寫一個函數有點難倒,deepEqual,取兩個值並返回true 只有它們具有相同的值或者具有相同 屬性的對象時,其值與遞歸調用deepEqual的 相比也相等。

要找出是否通過身份比較兩件事(使用=== 運算符)或通過查看它們的屬性,可以使用 typeof運算符。如果它爲兩個值生成「對象」,則應該進行深入比較。

我的代碼

function deepEqual(obj1, obj2) 
{ 
    var truefalse = undefined; 
    var type1 = typeof obj1; 
    var type2 = typeof obj2; 

// In case both are objects 
    if(type1 == 'object' && type2 == 'object') 
    { 
     var prop1 = []; 
     var prop2 = []; 
     for(var prop in obj1) 
      prop1.push(prop); 
     for(var prop in obj2) 
      prop2.push(prop); 

     // Test if both objects have the same number of properties 
     if(prop1.length == prop2.length) 
     { 

      // Test if all properties between them have the same names, 
      // by generating index for each property in prop1 against prop2 
      var indexArray = []; 
      for(var i = 0; i < prop1.length; i++) 
      { 
       var index = prop2.indexOf(prop1[i]); 
       indexArray.push(index); 
      }; 

      // If there's no "-1" anywhere in the indices generated 
      // (all properties are named the same between them), 
      // move on to value comparison for each property 
      if(indexArray.indexOf(-1) == -1) 
       { 
       for(var event in obj1) 
        { 
         if(deepEqual(obj1[event], obj2[event])) 
          truefalse = true 
         else 
          truefalse = false; 
        }; 
       } 

      // Different property names 
      else 
       truefalse = false; 
     } 

     // Different number of properties 
     else 
      truefalse = false; 
    } 

    // Either/both are not objects 
    else 
     truefalse = (obj1 === obj2); 

    return truefalse; 
} 

console.log(deepEqual({here: 3, object: 1}, {object: 1, here: 2})) 
// → true 

我的問題

通過一些調試,我懷疑是第一次比較我here屬性的值時(3和2),則返回false到我的truefalse變量,因爲它們彼此不同。但是,當for(var event in obj1) {...}循環移動到我的object屬性時,我的truefalse變量被重寫爲true,因爲它們都具有相同的值。

如果這是正確的診斷,有無論如何糾正這個錯誤?也許我應該使用or有條件的,但我不能想辦法將它與for循環結合起來。

謝謝你給這個初學者的所有幫助。

PS。在寫這篇文章時,我意識到我可以使用in測試來檢查兩個對象中的所有屬性是否都命名相同,但我現在太累了以編輯帖子。如果我那部分代碼看起來笨拙,我很抱歉。

+0

你的問題是,你在你的'爲(在OBJ1 VAR事件)'for循環每次迭代覆蓋你'truefalse'變量的值。 – zoom

回答

1

一般來說,你應該假設該函數返回true(等於),當發現任何差異時,立即返回false。

很簡單,改變truefalse的默認值。

var truefalse = true 

然後,替換

for(var event in obj1) 
{ 
    if(deepEqual(obj1[event], obj2[event])) 
     truefalse = true 
    else 
     truefalse = false; 
}; 

for(var event in obj1) 
{ 
    if(deepEqual(obj1[event], obj2[event]) == false) 
     return false 
}; 

現在它應該工作!

Rgrds,

+0

這對我來說確實非常適合初學者。起初我擔心會有同樣的問題,一個真正的匹配會扭轉錯誤的結果,最後我會得到一個錯誤的「真實」結果。但是,我現在意識到,在那種情況下,它甚至不會首先輸入「if」條款,而虛假的回報依然存在。再次感謝! – seismatica