浅い放射


0.基準値
  • JavaScriptは、データを元の値と参照値として変数に格納することができる.
  • 元の値は単純なデータです.数字列、文字列、boolean、undefinedなどがあります.
  • 参照値はメモリに格納されているオブジェクトです.オブジェクトを操作する場合、オブジェクト自体ではなくオブジェクトの参照が操作されます.
  • 元の値はコピー時に他のメモリにコピー値を割り当て、元の値とコピー値は互いに影響しない.
  • 参照値はコピー値ではなくコピー参照(メモリのアドレス)です.
  • 1.浅い放射線
  • 浅い複製は最上位のオブジェクトのみを生成することを意味し、内部オブジェクトは参照関係である.
  • Array.prototype.slice
  • Array.prototype.sliceターゲット配列から要素を取り出し、新しい配列を作成して値を入れる.start、endがない場合は、配列全体をコピーします.
  • let arr = [1, 2, 3];
    let copiedArr = arr.slice(); // copiedArr = [1, 2, 3];
    
    copiedArr.push(4);
    
    //arr = [1, 2, 3];
    //copiedArr = [1, 2, 3, 4];
  • オーバーラップ構造であれば内部要素が参照をコピーするので、完全コピーとは言えない.
  • let arr = [1, 2, [3, 4]];
    let copiedArr = arr.slice(); // copiedArr = [1, 2, [3, 4]];
    
    copiedArr[2].push(5);
    
    //arr = [1, 2, [3, 4, 5]];
    //copiedArr = [1, 2, [3, 4, 5]];
    Spread Operator
  • 展開演算子もコピーできますが、オーバーラップ構造はコピーできません.
  • let arr = [1, 2, [3, 4]];
    let copiedArr = [...arr]; // copiedArr = [1, 2, [3, 4]];
    
    copiedArr[2].push(5);
    
    //arr = [1, 2, [3, 4, 5]];
    //copiedArr = [1, 2, [3, 4, 5]];
    Object.assign
  • Object.assignソースオブジェクトからターゲットオブジェクトに属性をコピーできます.
  • これも深くコピーできない.
  • let arr = [1, 2, [3, 4]];
    let copiedArr = Object.assign([], arr); // copiedArr = [1, 2, [3, 4]];
    
    copiedArr[2].push(5);
    
    //arr = [1, 2, [3, 4, 5]];
    //copiedArr = [1, 2, [3, 4, 5]];
    2.深さ放射
  • 深度コピーとは、内部オブジェクトまで再生成してコピーすることである.
  • JSON.stringify, JSON.parse
  • JSON.stringifyデータを文字列に変換JSON.parse変形した文字を元のオブジェクトに戻す.
  • 文字列は元の値であり、上記の方法で新しいオブジェクトが生成される.
  • もちろん、重ね合わせ構造をコピーしてもよい.
  • let arr = [1, 2, [3, 4]];
    let copiedArr = JSON.parse(JSON.stringify(arr)); // copiedArr = [1, 2, [3, 4]];
    
    copiedArr[2].push(5);
    
    //arr = [1, 2, [3, 4]];
    //copiedArr = [1, 2, [3, 4, 5]];
  • ただし、関数が要素の場合はコピーできません.
  • ふくしゃ
  • 簡単に再帰関数で内部から再生成して複製してもよい.
  • let arr = [1, 2, [3, 4]];
    
    function copy(someArr) {
      let result = [];
      
      for (let el of someArr) {
        if (typeof el === 'object') {
          result.push(copy(el));
        } else {
          result.push(el);
        }
      }
      
      return result;
    }
    
    let copiedArr = copy(arr); // copiedArr = [1, 2, [3, 4]];
    
    copiedArr[2].push(5);
    
    //arr = [1, 2, [3, 4]];
    //copiedArr = [1, 2, [3, 4, 5]];
    ライブラリ(Lodash,Ramda)
  • 深度コピーを実現したライブラリがある.
  • const _ = require('lodash');
    
    let arr = [1, 2, [3, 4]];
    let copiedArr = _.cloneDeep(arr); // copiedArr = [1, 2, [3, 4]];
    
    copiedArr[2].push(5);
    
    //arr = [1, 2, [3, 4]];
    //copiedArr = [1, 2, [3, 4, 5]];
    3.終わりの言葉
  • javascript内での深度コピーは思ったよりずっと面倒だと思います.
  • 参照値のコピーについては認知しているが、実際に使用する際に深いコピーが必要かどうかは考慮する必要があるかもしれない.