倒れこむ

F.Uは蒸発しました。なんか書きます。

JavaScriptのDeepCopy

これ毎回悩んでるので結論から言うと

  • 自前で実装する
  • 汎用的な関数を用意する

の2つしかないです。 おそらく。

プリミティブ値(スカラー値)しかない時のDeepCopy

これは簡単です。

let obj = {
    a: 1
}
let deepCopy = Object.assign(Object.create(obj), obj); //DeepCopy

obj.a = 2;

console.log(obj) // a:2
console.log(deepCopy) // a:1 It's pretty good.

オブジェクトをネストしている時のDeepCopy

先程のコードは自身が別のオブジェクトを参照しているとうまくコピーされず、シャローコピーになってしまいます。

let obj = {
    myObj: {
        test: 1
    }
};

let deepCopy = Object.assign(Object.create(obj), obj); //DeepCopy?

obj.myObj.test = 2;

console.log(obj.myObj) // a:2 
console.log(deepCopy.myObj) // a:2    ... OH HELL.

うまくコピーする方法は… いくつかあるのですがコピペになるので割愛、最後にある参考記事を参照。

オブジェクト配列の場合(TypeScript)

任意Object配列の場合は以下のような書き方もできる

const arr: Model[] = [];

//なんかarrに突っ込む処理

const deepCopy = arr.map(model => new Model({...model}));

{...model}は、先程記述したObject.assign(Object.create(model), model) と等価(という認識ですが、間違ってたらすみません)です。

無論これもオブジェクトがネストされている場合はModelのコンストラクタで正しくnewしげあてる必要があります。

class Model {
    private myObj: NestedModel;
    constructor(_) {
        this.myObj = new NestedModel(_.myObj); 
    }
}

うーんめんどくさいですね。 しかし裏ワザは言うほどなさそうなのでしっかり理解して書いていきましょう。

以下参考にした記事

kuroeveryday.blogspot.jp

www.webprofessional.jp