[JS]浅い放射と深い放射(feat.反応器の中で深い放射...?)


JavaScriptのレプリケーションの概念について


リファレンスデータをよりよくコピーするにはどうすればいいですか?

浅いコピー


オブジェクトを含む変数を別の変数に割り当てると、データコピーではなく参照が生成されます.したがって、変数のデータを変更すると、他の変数のデータも変更されます.
const man1 = {name:"GO"};

const man2 = man1;

man1.name = "Garden";

console.log(man2.name) //Garden
console.log(man1 === man2) //true -> 같은 데이터주소를 바라보고 있다.
man 2では、man 1をもう1つ作成するのではなく、そのデータのメモリアドレスを受信し、最終的に同じデータを表示します.

深度コピー


同じデータを表示するのではなく、別の構造を持つオブジェクトを作成して単独で使用する場合は、深度コピーを行います.
const man1 = { name:"GO"};

const man2 = Object.assign({ }, man1);

man1.name = "Garden";

console.log(man2.name) //Go -> 다른 메모리 주소의 데이터니까 man2의 값이 변하지 않는다. 
console.log(man1 === man2) //false -> 형태는 같지만, 각 자 다른 메모리 주소에 저장되어 있는 데이터이다. 
データ参照ではなくオブジェクトのシェイプをコピーすることで、1つのオブジェクトが変更され、別のオブジェクトのデータは影響を受けません.
私が理解している浅い放射線、深い放射線
基本データは、新しいデータが割り当てられたときに使用されます.
各変数が参照するデータ領域のアドレスが異なるため、a,bは異なるデータとなる.
ただし、参照データ(オブジェクト)がオブジェクトのプロパティを変更した場合、参照データ領域のアドレスは変更されないため、同じデータとみなされます->参照データを可変と呼ぶ理由は、オブジェクトのプロパティ値を変更できるからです.
ただし、オブジェクト自体(オブジェクトのプロパティではなく)を再割り当てすると、オブジェクトの形状が同じであってもデータ領域のアドレスが異なるため、2つのオブジェクトは異なるオブジェクトと見なされます.(深いコピー)
->この原理を使用して、ステータス変更時に再表示します.

深度レプリケーションの一般的な方法


Object.assign()

Object.assign()は、オブジェクト形式のデータを簡単にマージできる関数です.
const Obj = {a:1};

const newObj = Object.assign({}, Obj); // 빈 Object에 Obj를 병합하여 반환

console.log(newObj); // {a:1} 
console.log(Obj === newObj);// false -> 형태는 같으나 둘은 다른 데이터를 바라보고 있음
コピーするオブジェクトを
  • 空のオブジェクトにマージします.これにより、新しいnewObjectが返されます.その形式はObjectですが、実際には空のObjectとObjectが統合されています.
  • Spread Operation

    const Obj1 = {a:1, b:2};
    const Obj2 = {c:3};
    const Obj3 = {...Obj1, ...Obj2};
    
    console.log(Obj3); // {a:1, b:2, c:3}
  • でコピーしたいオブジェクトの前に...を付けると、整列またはオブジェクト形式のカッコを使用できます.
    オブジェクトだけでなく、配列でも同じ内容を使用できます.
  • 😎なぜ反応の中で浅い放射線、深い放射線の概念を熟知しなければならないのか!!


    応答で「Spread Operator」を使用して深度コピーを行うと、オブジェクトの不変性を維持できます.
    でもなぜ不変性を保つのか...?
    ステータス(データ)が変化すると、リアクターは再レンダリングする必要があるため、ステータスが以前とは異なるデータになっていることを検出できる必要があります.
    例を見てください.
    function App(){
      const [inputs, setInputs] = useState({
        username = "",
        email = "",
      });
      const { username, email } = inputs;
      
      const onChange = (e) => {
        const { name, value } = e.target; 
        
        setInputs({
          ...inputs, //📍 스프레드연산자
          [name]:value,
        });
      }; 
    inputsステータスにはkey(ユーザー名、email)があり、value(string)は空です。 setInputs()は、高速演算子を使用して既存の入力(state)を同じ位置にコピーし、新しいstateを生成します。形状は同じですが、データが違う→電子演算子で深度コピー! ユーザーがinputウィンドウに値を入力すると、valueに割り当てられます。 これにより、既存の入力(値が空)とは異なる新しい入力(入力された値が割り当てられた)が生成されます。

    📍 Spread Operatorは、変数領域が参照するデータ領域のアドレスを元のデータが参照するデータ領域のアドレスとは異なる.このコードでは、電子演算子も元のデータとは異なるデータを生成し、不変性(深さレプリケーション)を確保します.リアクターは、状態が変化していることを検出し、レンダリングすることができます.
    📍 immerライブラリを使用しても不変性を確保できます!

    😭注意事項!


    深度コピーは、現在のDepthのみをコピーし、深度コピーはしません.
    たとえば、
    深さ2のオブジェクトは、電子演算子を使用してObj2に割り当てられます.
    const Obj1 = { a: 
                  	{ b : 1 }
                 };
    const Obj2 = { ...obj1 };
    
    console.log(Obj2) // { a: { b : 1 } };
    console.log(Obj1 === Obj2) //false
  • Obj 1とObj 2の形態は同じで、それぞれ異なるメモリアドレスを見ています.
  • でも、放射線が深いのは一番外の深さだけ…!!
    const Obj1 = {a :{b:1}};
    const Obj2 = { ...Obj1};
    
    console.log(Obj2) // { a: { b : 1 } };
    console.log(Obj1 === Obj2) //false
    
    console.log(Obj1.a === Obj2.a) // true...🙄😨😵
  • の2番目の深さ以上の要素は、参照値、すなわち浅いレプリケーションを伝達する.Object.assign()を使うのも同じです.
  • では、どのようにしてすべての深さを深部に完璧にコピーしますか?

    完全に深くコピーする方法


    再帰実行深度コピー


    深くコピーするシェイプに基づいて、再帰関数を作成してコピーします.問題は...使用するオブジェクトの深さが深いほど、時間の複雑さが高くなります.

    LodashのCloneDeep関数の使用


    JAvascript高次関数セットおよび関数型ライブラリ.
    LodashのCloneDeep関数を使用すると、完全に深度コピーが可能です.

    JSON.parse()とJSON。stringgify()関数の使用


    JSON.stringify関数を使用して、オブジェクト全体を文字列に変換し、JSONを再開します.parse関数を使用して文字列をオブジェクトに変換します.
    これにより、文字列に変換した瞬間に参照値が切断されるので、新しいオブジェクトとして作成して使用することができます.
    ただし、JSON関数は大量のリソースを消費する関数であるため、性能の悪い部分を考慮する必要がある.
    [注意]
    https://heo-dev-0229.tistory.com/47