8

私はこの質問をチェックしていましたJavascript Deep Comparison質問 者の解決策は私を納得させなかったので、私は問題を分析しようとし、それを思いつきました

var obj = {here: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1}));
// → false
console.log(deepEqual(obj, {here: 2}));
// → true
function deepEqual(a,b)
{
  if( (typeof a == 'object' && a != null) &&
      (typeof b == 'object' && b != null) )
  {
     var count = [0,0];
     for( var key in a) count[0]++;
     for( var key in b) count[1]++;
     if( count[0]-count[1] != 0) {console.log('1');return false;}
     for( var key in a)
     {
       if(!(key in b) || !deepEqual(a[key],b[key])) {console.log('2');return false;}
     }
     for( var key in b)
     {
       if(!(key in a) || !deepEqual(b[key],a[key])) {console.log('3');return false;}
     }  
  }
  console.log('a:'+a+' b:'+b);
  return a===b;
}
obj === { here:2 }

このコードは最後のテスト ( console.log(deepEqual(obj, {here: 2})) ) に失敗しますが、メモリ内のインスタンスが異なるにもかかわらず、オブジェクトがそれぞれ等しいキーと値を持っている場合、オブジェクトが完全に等しいと見なすロジックは私を納得させません。私の「解決策」に問題がありますか、それとも間違いは演習の前提にありますか? リンクした質問に記載されているコードは有効ですか?

hikinthru が言及するのを忘れたリソース ( http://eloquentjavascript.net/04_data.html#exercise_deep_compare )

4

1 に答える 1

16

あなたがリンクした質問が話している「深い平等」と「厳密な平等」は2つの異なるものです。「深い平等」とは、あなたが言ったように「等しいキーと等しい値」を意味します。オブジェクトの「厳密な等価性」は「同じインスタンス」を意味します。厳密な等価性は深い等価性を意味しますが、オブジェクトは厳密に等価でなくても深い等価性を持つことができます。

a === b必要なループが 1 つだけであるため、コードはやや非効率的ですが、elseブロックをチェックインしreturn trueてループの後に実行すると、正しく動作しforます。これは、文字列や数値などのプリミティブ値とは別にオブジェクトを処理する必要があるためです。わかりやすくするためにログを削除しましたが、スタイルを維持しようとしました。

var obj = {here: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1}));
// → false
console.log(deepEqual(obj, {here: 2}));
// → true
console.log(obj === { here:2 });
// → false
function deepEqual(a,b)
{
  if( (typeof a == 'object' && a != null) &&
      (typeof b == 'object' && b != null) )
  {
     var count = [0,0];
     for( var key in a) count[0]++;
     for( var key in b) count[1]++;
     if( count[0]-count[1] != 0) {return false;}
     for( var key in a)
     {
       if(!(key in b) || !deepEqual(a[key],b[key])) {return false;}
     }
     for( var key in b)
     {
       if(!(key in a) || !deepEqual(b[key],a[key])) {return false;}
     }
     return true;
  }
  else
  {
     return a === b;
  }
}

于 2016-07-16T23:08:38.500 に答える