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

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

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

Takato Ezaki

Takato Ezaki小中高の塾講師からエンジニア

投稿者プロフィール

福岡で Web 系のエンジニアをしています。

中高の理科教師免許を取り、起業に 2 年間トライした後エンジニアの道へ入りました。

化学反応の中では Belousov-Zhabotinsky 反応が大好きです。

この著者の最新の記事

関連記事

コメントは利用できません。

募集中!(o゜▽゜)o

エンジャパン
求む、社長!
follow us in feedly

コッチもヨロシク!





最近のネタ!

  1. 2019-10-14

    エンジニア的・知っておきたいトップレベルドメイン

    多様化するトップレベルドメイン 皆さんは自分のホームページなどなど、持っていますか? ホームペー…
  2. 2019-10-9

    2019年9月度社員総会&懇親会@Nagoya

    名古屋オフィスのおーてぃーです。 暑い暑い8月が過ぎ、日増しに涼しくなり、過ごしやすい季節になって…
  3. 2019-10-9

    2019年 8月度・第37回福岡社員総会&懇親会

    はじめに 令和元年8月の福岡社員総会! 8月上旬、正確にいえば8月9日(金曜日)、福岡市は博多にて…
  4. 2019-10-8

    2019年9月度社員総会&懇親会@Osaka

    2019年9月13日(金)、大阪社員総会&懇親会が開催されました! その様子をお届けします! 社員…
  5. 2019-10-7

    Namecheap のロゴメーカーで簡単にオシャレなロゴが作成できる

    ロゴ作成って意外に難しい みなさん、Web サービス作ってますか? Web で何かしらサービスを…
ページ上部へ戻る

当サイトに掲載されているコンテンツ(文書、画像等)は、許可なく複製・転用等する事を禁じます。

「フェアネス方式®」(登録6150741)は、日本国内における株式会社エージェントグローの登録商標です。

当サイトでは最低限必要と考えられる場合において、会社名/サービス名/商品名などを記載している場合があります。
これらはあくまでも説明の必要性に応じて用いているものであり、各社の権利等を侵害を目的とするものではございません。
不適切と考えられる場合には、当社お問い合わせフォームよりご連絡ください。

当サイトでは®や™などの表記を省略させていただいております。