Shallow Copy & Deep Copy?? なんだよ.これ.


1.浅いレプリケーションと深いレプリケーションについて

  • レプリケーション・オブジェクトの参照値(アドレス値)を浅くコピーし、レプリケーション・オブジェクトの実際の値を深くコピーします.
    JavaScriptでは、元の値と参照値の2種類のデータ型の値が存在します.
  • 元のタイプの値は、新しいメモリ領域格納値とは独立しているため、深度レプリケーションです.
  • 参照タイプの値は浅いコピーです.
  • の2つのタイプの最大の違いは、元のタイプが変更されると参照タイプも変更されますが、元のタイプは変更されません.
  • // 원시 타입의 깊은 복사
    let a = '원본 데이터';
    let b = a;
    
    a = '수정 데이터';
    
    console.log(a); // '수정 데이터'
    console.log(b); // '원본 데이터'
  • 元のタイプは、レプリケーション時に値自体を含む独立したメモリを生成するため、aを再割り当てしてもbに影響を及ぼさない.
  • // 참조 타입의 얕은 복사
    let a = {name:'원본 데이터'};
    let b = a;
    
    a.name = '수정 데이터';
    
    console.log(a); // '수정 데이터'
    console.log(b); // '수정 데이터'
  • の新しい値で変数値を再割り当てすると、変数値も変化することがわかります.すなわち,データはそのまま1つのデータを生成するのではなく,そのデータのメモリアドレスを伝達し,最終的に1つのデータを共有する.
  • 1 - 1. 浅いレプリケーション

  • オブジェクトをコピーすると、そのオブジェクトのみがコピーされ、新しいオブジェクトが作成されます.
  • 複製オブジェクトのインスタンス変数は、元のオブジェクトのインスタンス変数と同じメモリアドレスを参照する.
  • したがって、メモリアドレスの値が変更されると、元のオブジェクトとコピーされたオブジェクトのインスタンス変数の値が変更されます.

    1) Array.prototype.slice()


    これは
  • 浅層放射の一例である.既存の配列から新しい配列を抽出して返す方法(インデックスの開始から終了まで).start、endを設定しない場合は、既存の配列をすべて浅くコピーします.
  • const original = ['a',2,true,4,"hi"];
    const copy = original.slice();
    
    console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
    
    copy.push(10);
    
    console.log(JSON.stringify(original) === JSON.stringify(copy)); // false
    
    console.log(original); // [ 'a', 2, true, 4, 'hi' ]
    console.log(copy); // [ 'a', 2, true, 4, 'hi', 10 ]
  • は既存のアレイに影響を及ぼさず、深度レプリケーションのように見えるかもしれませんが、元の値を格納する1次元アレイにすぎません.元の値は基本的に深いコピーです.
  • const original = [
      [1, 1, 1, 1],
      [0, 0, 0, 0],
      [2, 2, 2, 2],
      [3, 3, 3, 3],
    ];
    
    const copy = original.slice();
    
    console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
    
    // 복사된 배열에만 변경과 추가.
    copy[0][0] = 99;
    copy[2].push(98);
    
    console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
    
    console.log(original);
    // [ [ 99, 1, 1, 1 ], [ 0, 0, 0, 0 ], [ 2, 2, 2, 2, 98 ], [ 3, 3, 3, 3 ] ]출력
    console.log(copy);
    // [ [ 99, 1, 1, 1 ], [ 0, 0, 0, 0 ], [ 2, 2, 2, 2, 98 ], [ 3, 3, 3, 3 ] ]출력
  • 一次元アレイではなく、重複構造を有する二次元アレイの場合、浅い放射が実行される.
  • const original = [
      {
        a: 1,
        b: 2,
      },
      true,
    ];
    const copy = original.slice();
    
    console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
    
    // 복사된 배열에만 변경.
    copy[0].a = 99;
    copy[1] = false;
    
    console.log(JSON.stringify(original) === JSON.stringify(copy)); // false
    
    console.log(original);
    // [ { a: 99, b: 2 }, true ]
    console.log(copy);
    // [ { a: 99, b: 2 }, false ]
  • 配列内でオブジェクトを変更する場合は、浅いレプリケーションが実行されます.ただし、元の値は基本的に深度コピーであるため、エクスポートされた値は既存の変数の値とは異なることがわかります.
  • 2)Spread演算子(展開演算子)

    const obj = {
      a: 1,
      b: {
        c: 2,
      },
    };
    
    const newObj = { ...obj };
    
    newObj.b.c = 3;
    
    console.log(obj); // { a: 1, b: { c: 3 } }
    console.log(obj.b.c === newObj.b.c); // true
  • ビットの例から、Spread演算子も浅いコピーを行うことが分かる.
  • 1~2複製

  • デプスコピーの目的は、既存のオブジェクトの値のみをコピーして、異なる場所で使用することです.
  • 1 ) JSON.parse & JSON.stringify

  • JSON.stringify()オブジェクトをjson文字列に変換すると、元のオブジェクトとの参照が切断されます.
  • オブジェクトをJSON文字列に戻した後、JSON.parse()を使用して元のオブジェクトとして再作成します.
  • const obj = {
      a: 1,
      b: {
        c: 2,
      },
    };
    
    const newObj = JSON.parse(JSON.stringify(obj));
    
    newObj.b.c = 3;
    
    console.log(obj); // { a: 1, b: { c: 2 } }
    console.log(obj.b.c === newObj.b.c); // false
  • この方法は簡単で実行しやすいが、他の方法に比べて速度が遅いという欠点があり、オブジェクトが関数であれば未定義として処理される.
  • function deepCopy(obj) {
      if (obj === null || typeof obj !== "object") {
        return obj;
      }
    
      let copy = {};
      for (let key in obj) {
        copy[key] = deepCopy(obj[key]);
      }
      return copy;
    }
    
    const obj = {
      a: 1,
      b: {
        c: 2,
      },
      func: function () {
        return this.a;
      },
    };
    
    const newObj = deepCopy(obj);
    
    newObj.b.c = 3;
    console.log(obj); // { a: 1, b: { c: 2 }, func: [Function: func] }
    console.log(obj.b.c === newObj.b.c); // false
  • この問題を解決するために,深さレプリケーションを実現するCustom再帰関数を用いた.でも、複雑です.
  • の最後の部分


    =>浅い放射線と深い放射線の光は文字通り理解できませんが、そうらしいです。これらは他にも多く使われているので、多くの例を参考にして学ぶ必要があります...ううう