自主的20%るぅる

各々が自主的に好き勝手書くゆるふわ会社ブログ

[JavaScript] オブジェクト & 配列のイマドキなコピー方法 (スプレッド構文)

オブジェクトや配列のコピーってどうやって書きますか?

皆さん JavaScript 書いてますか?

JavaScript をガッツリ書いていると、たまに必要になるのが
オブジェクトや配列のコピー。

みなさんどうやってますか?

今回は、イマドキ(ES6)な方法でのコピーをご紹介しましょう。

オブジェクトのコピー

まずはオブジェクトから。

最初に確認しておきますが、もちろん、これはダメですよね。

var test = { a: 10 };
var test_copy = test;

test_copy.a = 20;

console.log(test);

test から test_copy に代入。
これでは testtest_copy はコピーされておらず、同じものを見ています。

実際実行してみると…

[object Object] {
  a: 20
}

test_copy を変更したはずなのに、 testa プロパティも変更されていますね。

これまでの方法

で、これまではこんな感じでコピーしてきました。

var test = { a: 10 };
var test_copy = Object.assign({}, test);

Object.assign() を使う方法ですね。
元々この関数は、一番最初に渡されたオブジェクトに、
その後ろに渡されたオブジェクトを結合していく関数です。

ということで、今回は新しく作った空オブジェクト {}
test を結合しているので、できあがる内容は test と同じものだけど、オブジェクト自体は別物となるのですね。

イマドキな方法

次に、イマドキな方法でコピーすると、こう。

var test = { a: 10 };
var test_copy = { ...test }

なんだか不思議な記法ですが、やっていることは先ほどとほぼ一緒です。

ここで重要なのは ...test の部分。

これはスプレッド構文と呼ばれるもので、
さっくり説明すると、その場で中身を全部ぶちまけると言うものになります。

スプレッド構文

スプレッド構文 を使うと、関数呼び出しでは 0 個以上の引数として、Array リテラルでは 0 個以上の要素として、Object リテラルでは 0 個以上の key-value のペアとして、Array や String などの iterable オブジェクトをその場で展開します。 関数呼び出し myFunction(…iterableObj); Array リテラル […iterableObj, ‘4’, ‘five’, 6]; Object リテラル(ECMAScript 2018 の新機能) let objClone = { …obj }; apply を置き換える Array の要素を引数にして関数を呼び出すには Function.prototype.apply を使うのが一般的です。 function myFunction(x, y, z) { } var args =

つまり、 { ...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 から追加されたもので、あまりなじみがない書き方ではあります。
が、一度使ってしまうとその便利さに驚かれるのではないでしょうか。

細かいところですが、簡単にオブジェクトのコピーなどができるスプレッド構文、
是非使ってみてくださいね。

Let’s share this article!

{ 関連記事 }

{ この記事を書いた人 }

Takato Ezaki
takato_ezaki
記事一覧