[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
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...🙄😨😵
Object.assign()
を使うのも同じです.完全に深くコピーする方法
再帰実行深度コピー
深くコピーするシェイプに基づいて、再帰関数を作成してコピーします.問題は...使用するオブジェクトの深さが深いほど、時間の複雑さが高くなります.
LodashのCloneDeep関数の使用
JAvascript高次関数セットおよび関数型ライブラリ.
LodashのCloneDeep関数を使用すると、完全に深度コピーが可能です.
JSON.parse()とJSON。stringgify()関数の使用
JSON.stringify関数を使用して、オブジェクト全体を文字列に変換し、JSONを再開します.parse関数を使用して文字列をオブジェクトに変換します.
これにより、文字列に変換した瞬間に参照値が切断されるので、新しいオブジェクトとして作成して使用することができます.
ただし、JSON関数は大量のリソースを消費する関数であるため、性能の悪い部分を考慮する必要がある.
[注意]
https://heo-dev-0229.tistory.com/47
Reference
この問題について([JS]浅い放射と深い放射(feat.反応器の中で深い放射...?)), 我々は、より多くの情報をここで見つけました https://velog.io/@g0garden/JS-얕은복사와-깊은복사feat.깊은복사를-제대로テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol