オブジェクトや配列のコピーってどうやって書きますか?
皆さん JavaScript 書いてますか?
JavaScript をガッツリ書いていると、たまに必要になるのが
オブジェクトや配列のコピー。
みなさんどうやってますか?
今回は、イマドキ(ES6)な方法でのコピーをご紹介しましょう。
オブジェクトのコピー
まずはオブジェクトから。
最初に確認しておきますが、もちろん、これはダメですよね。
var test = { a: 10 }; var test_copy = test; test_copy.a = 20; console.log(test);
test
から test_copy
に代入。
これでは test
と test_copy
はコピーされておらず、同じものを見ています。
実際実行してみると…
[object Object] { a: 20 }
test_copy
を変更したはずなのに、 test
の a
プロパティも変更されていますね。
これまでの方法
で、これまではこんな感じでコピーしてきました。
var test = { a: 10 }; var test_copy = Object.assign({}, test);
Object.assign()
を使う方法ですね。
元々この関数は、一番最初に渡されたオブジェクトに、
その後ろに渡されたオブジェクトを結合していく関数です。
ということで、今回は新しく作った空オブジェクト {}
に
test を結合しているので、できあがる内容は test と同じものだけど、オブジェクト自体は別物となるのですね。
イマドキな方法
次に、イマドキな方法でコピーすると、こう。
var test = { a: 10 }; var test_copy = { ...test }
なんだか不思議な記法ですが、やっていることは先ほどとほぼ一緒です。
ここで重要なのは ...test
の部分。
これはスプレッド構文と呼ばれるもので、
さっくり説明すると、その場で中身を全部ぶちまけると言うものになります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
つまり、 { ...test }
は test
が持っている a: 10
をその場に展開するので
{ a: 10 }
と書いているのと同義ということになりますね。
よって、test の内容と全く同じ内容でオブジェクトを作り直す形になるので、
これだけでコピーができてしまうのです。
ちなみに、スプレッド構文は単純にその場に内容を展開しているだけなので、
値の追加もできます。
var test = { a: 10 }; var test_copy = { ...test, b: 20 };
こんな感じで書けば、 { a: 10, b: 20 }
というオブジェクトが作れるのですね。
もちろん、スプレッド構文を何個も書いても良いので
var test1 = { a: 10 }; var test2 = { b: 20 }; var test_copy = { ...test1, ...test2 };
こんなのも OK。
配列のコピーもおんなじ感じで。
配列のコピーも、同じようにスプレッド構文を使って書くことができます。
var test = [10, 20, 30]; var test_copy = [ ...test ];
このように書くだけで、簡単に配列もコピーできるのですね。
これも、配列の結合などでもよくつかる場面があります。
var test1 = [10, 20, 30]; var test2 = [40, 50]; var test_copy = [ ...test1, ...test2 ];
こんな感じで書くだけで簡単に結合できちゃいます。
もうちょっと言うとこんなことも。
var test = [10, 20]; var test_func = function (a, b) { console.log(a + b); }; test_func(...test); // 30 と表示される
関数の引数でスプレッド構文を使うことで、配列が展開され、
a には 10, b には 20 が入ります。
これはあまり使いどころはないですが、
引数が多い関数を使う場合は使ってみると便利かもしれないですね。
スプレッド構文、使ってみよう!
スプレッド構文は ES6 から追加されたもので、あまりなじみがない書き方ではあります。
が、一度使ってしまうとその便利さに驚かれるのではないでしょうか。
細かいところですが、簡単にオブジェクトのコピーなどができるスプレッド構文、
是非使ってみてくださいね。