バニラJavaScriptのオブジェクトの深い等値検査👨‍👦


あなたはJavaScriptでお互いに2つのオブジェクトを比較するために必要な状況で自分自身を発見しましたか?おそらく、JavaScriptはこの問題に対するネイティブの解決策を提供していないことがわかった.このチュートリアルでは、このための独自の実装を構築します!
次のようなことを学びます.
  • は、値によるパス対参照
  • によって、パスする
  • オブジェクト.keys ()メソッド
  • 再帰関数を作成する
    あなたはlodashライブラリをつかむことができるし、2つのオブジェクトの深い品質のチェックを行うには、.isEqualメソッドを使用することができますが、それは良い私たち自身がバニラJavaScriptを実践するソリューションを作成する練習です.
    次のオブジェクトを持っています
    const obj1 = { name: 'Peter', stats: { points: 45, isActive: false }};
    const obj2 = { name: 'Peter', stats: { points: 45, isActive: false }};
    
    console.log(obj1 === obj2) // returns false
    
    これらの2つのオブジェクトはまったく同じですが、JavaScriptはfalseを返します.なぜ?
    これは、JavaScriptの文字列と数字のプリミティブがその値で比較されるためです.一方、オブジェクトは参照により比較される.
    JavaScriptは、メモリ内の独自の場所に作成する各オブジェクトを割り当てます.ですから、オブジェクトが正確に同じコンテンツを持っている場合でも、その参照(メモリ内の場所)は異なります!

    関数の作成を始めましょう.2つの引数をとるcompareObjectsという関数を設定します.まず、2つの引数が同じ型であるかどうかを調べます.
    const compareObjects = (a, b) => a === b ? true : false;
    
    const obj1 = { name: 'Peter', stats: { points: 45, isActive: false }};
    
    compareObjects(obj1, obj1) // returns true
    
    次に、2つの引数が実際にobject型で、nullの値でないかどうかをチェックします.タイプ変換を避けるために!=の代わりに!==を使用します.
    const compareObjects = (a, b) => {
     if (a === b) return true;
    
     if (typeof a != 'object' || typeof b != 'object' || typeof a == null || typeof b == null) return false;
    }
    
    次に、両方のオブジェクトのオブジェクトキーの長さを確認します.同じ長さがない場合、オブジェクトは同じではないことを確認します.
    ...
    let keysA = Object.keys(a), keysB = Object.keys(b);
     if (keysA.length != keysB.length) return false;
    ...
    
    次に、我々はfor ofループでKeysa配列のキーをループします.オブジェクトにはfor ofを使用します.
    このループ内でキーキー配列内のすべてのキーが存在するかどうかを調べます.次に、すべてのキーの値をfor in関数に戻し、関数を再帰的に(自分自身を呼び出す)ことによって比較します.
    値のキーの1つが同じでないとすぐに、ループと関数を停止し、falseを返します.
    ...
    for (let key of keysA) {
        if (!keysB.includes(key) || !compareObjects(a[key], b[key])) return false;
    }
    ...
    
    
    また、メソッドが同じであるかどうかをチェックしたい場合、2つの値を比較するときに関数を文字列に変換することでこれを行います.
    ...
    if (typeof a[key] === 'function' || typeof b[key] === 'function') {
       if (a[key].toString() != b[key].toString()) return false;
    }
    ...
    
    ループがすべてのキーをチェックして、すべてのネストされた値をそれ自身の関数に渡して、Noneが返されたならば、falseを返しました.
    完全な機能:
    const compareObjects = (a, b) => {
     if (a === b) return true;
    
     if (typeof a != 'object' || typeof b != 'object' || a == null || b == null) return false;
    
     let keysA = Object.keys(a), keysB = Object.keys(b);
    
     if (keysA.length != keysB.length) return false;
    
     for (let key of keysA) {
       if (!keysB.includes(key)) return false;
    
       if (typeof a[key] === 'function' || typeof b[key] === 'function') {
         if (a[key].toString() != b[key].toString()) return false;
       } else {
         if (!compareObjects(a[key], b[key])) return false;
       }
     }
    
     return true;
    }
    
    このチュートリアルをフォローしてくれてありがとうございます.🧠
    さらに参考のために本の雄弁なJavaScriptを見てください.