shallow copy, deep copy

12721 ワード

TOC


  • shallow copy

  • deep copy
  • どの言語にも浅いcopy、deepcopyに関する物語があると思います.

    要点


    JSで任意のオブジェクトをコピーします.
    JSのオブジェクトはPrimitive値に対してdeep copyを行う.
    ポイントは、他のオブジェクトが浅いコピーを行うことです.

    boolean



    null



    undefined



    string



    number



    浅いコピーが発生した場合


    たとえば、Primitive以外のオブジェクトでは、浅いコピーが発生します.

    Array



    copyは全部直して、aryも一緒に直しました.
    これはary,copyが同じ変数を参照することを意味する.
    もう一つ下の画像を見て

    ary配列で各オブジェクトを宣言します.
    プロトタイプによるコピー
    copyを変更してaryを再度呼び出しますが、変更はありません.
    copyとary
    そのままdeepcopyになってしまい、お互い全く関係ないのでしょうか?
    他のものを試してみましょう.

    ary[0].aオブジェクトを変更しcopyを表示した結果、値が変更されました.
    ではdeepcopyについてお話しします

    deep copy

    const deepCopyFunction = (inputObject) => {
      let outputObject, value, key;
      outputObject = Array.isArray(inputObject) ? [] : {}; // Create an array or object to hold the values
    
      if (typeof inputObject !== "object" || inputObject === null) {
        return inputObject; // Return the value if inputObject is not an object
      }
    
      for (key in inputObject) {
        value = inputObject[key];
        outputObject[key] = deepCopyFunction(value); 
       // Recursively (deep) copy for nested objects, including arrays
      }
      return outputObject;
    }
    
    let originalArray = [10, 20, { name: "Ayush", age: 27 }];
    let deepCopyArray = deepCopyFunction(originalArray);
    originalArray[1] = 15;
    originalArray[2].name = "Verma";
    
    console.log(originalArray); //[10, 15, { name: "Verma", age: 27 }];
    console.log(deepCopyArray); //[10, 20, { name: "Ayush", age: 27 }];
    [出典]https://javascript.plainenglish.io/shallow-copy-and-deep-copy-in-javascript-a0a04104ab5c
    上のブログはcopyについてよく説明しています.
    deep copyの原因はたくさんあるかもしれませんが、元のファイルを参照したくない場合は、deep copyは必須の実装要素になります.
    従って、deepcopyは、上記の純粋なjs法を用いて実現することができ、
    有名なライブラリlodash、ramda、rdfcを使用します.
    // lodash
    import { clone, cloneDeep } from "lodash" // Alternatively: Import just the clone methods from lodash
    const nestedArr = [["1"] ,["2"] ,["3"]];
    const shallowCopyWithLodashClone = _.clone(nestedArr)
    console.log(nestedArr[0] === shallowCopyWithLodashClone[0]);
    // true -- Shallow copy (same reference)
    const deepCopyWithLodashCloneDeep = _.cloneDeep(nestedArray)
    console.log(nestedArr[0] === deepCopyWithLodashCloneDeep[0]);
    // false -- Deep copy (different reference)
    // ramda
    
    import R from "ramda" // Import the entire ramda library
    // import { clone } from "ramda" // Alternatively: Import just the clone methods from ramda
    const nestedArr = [["1"] ,["2"] ,["3"]];
    const deepCopyWithRamdaClone = R.clone(nestedArray)
    console.log(nestedArr[0] === deepCopyWithRamdaClone[0]);
    // false -- Deep copy (different reference)
    // rdfc
    
    const clone = require('rfdc')() // Returns the deep copy function
    clone({a: 37, b: {c: 3700}}) // {a: 37, b: {c: 3700}}