どうも、はぐっです・ω・♪
JavaScript(ES6/ES2015)でオブジェクトをコピー」
もう、babelを利用してES6/ES2015でJavaScriptを書いている人もだいぶ増えて来たことかと思います。で、様々な場面でオブジェクトを扱うことが多くあるはずっ。
んで、コピーしたいなんてこともあるはずっ。
そんなとき、コピーの仕方はいくつかあると思いますが、ここでは二つのやり方を。
コピーの方法
jQueryを利用してオブジェクトをコピー
JavaScript界の大ベテラン、「jQuery」
こいつに、オブジェクトをコピーする時に使えるメソッドが用意されています。
(本来の目的はオブジェクトのマージだったり。)
$.extend
使い方は
let firstObj = {
a: 'a',
b: {
a: 'a',
b: {
a: 'a'
}
}
};
let secondObj = $.extend(true, {}, firstObj);
はいっ、こぴー。
引数はこちら。
第一引数 : ディープコピーかどうか(省略可)
第二引数 : マージのもととなるオブジェクト
第三引数以降 : マージするオブジェクト(いくつでも)
ん?
ディープコピー?
そう!
今回はここがポイントです!
ディープコピーとは
まぁ、「とは」っていうほど定義が必要なものではなくて、
deep:深い
つまり、深いコピーをするか、浅いコピーをするか。
下の階層まで再帰的にコピーするか。
ここ、割と大事。
ES6/ES2015を利用してオブジェクトをコピー
ES6/ES2015になって、
待ってましたー!!!!
な機能が様々追加され、いろいろとはっぴーになったわけですが、
その中の一つ。
Object.assign
こいつ。
使い方は
let firstObj = {
a: 'a',
b: {
a: 'a',
b: {
a: 'a'
}
}
};
let secondObj = Object.assign({}, firstObj);
はいっ、こぴー。
第一引数 : マージのもととなるオブジェクト
第二引数以降 : マージするオブジェクト(いくつでも)
うむ。
さっきのjQueryのextendと使い方自体はそうかわら・・・
ディープは!?
そう、ここが違うのです。
Object.assignは、シャローコピー(ディープコピーと違って浅いコピー)なのです!!
これね、困る時があるんですよ。
コピーの方法による違い
例えば
let firstObj = {
a: 'a',
b: {
a: 'a',
b: {
a: 'a'
}
}
};
があったとしてですよ。
$.extendの場合
let secondObj = $.extend(true, {}, firstObj);
secondObj.b.a = 2;
console.log(firstObj.b.a); // 1
console.log(secondObj.b.a); // 2
この場合、出力は
1: a
2: 2
となります。
Object.assignの場合
let secondObj = Object.assign({}, firstObj);
secondObj.b.a = 2;
console.log(firstObj.b.a); // 1
console.log(secondObj.b.a); // 2
この場合、出力は
1: 2
2: 2
となります。
ほらああああああああああ!!!
こういうところで違いがでてくるんですよ!
だから言ったじゃないですかあああ!
…こほん。
つまりね、
オブジェクトがプロパティとしてオブジェクトを持っている時、
シャローコピー(Object.assign)だと同じ参照
ディープコピー($.extend(true))だと別参照
となるわけですね。
みなさま、くれぐれもオブジェクトのコピーは慎重に。
ES6/ES2015のご利用は計画的に。