2016/12/22更新

[Javascript] ES6のスプレッド演算子(Spread Operator)を使いこなす

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
最近はES6で書かれたライブラリも増えてきましたね。そんな中、...valsのような表記を目にすることもあるのではないでしょうか?今日はその...についてブログを書きたいと思います。使いこなせると便利です。

※注:Spread Operatorの翻訳でスプレッド演算子と訳されているので本記事でもそれに従っていますが、演算子と言っていいのかは少し謎です。


画像

目次




実際に試すには

本記事のコードはNode.jsで動作します。最新のNodeJSを準備して試してみてください。
# 今回のファイル名は「spread_operator.js」とします.
$ node spread_operator.js
また、ブラウザで利用する場合にはBabelによるコンパイルが必要です。Babelの使い方などは「次世代JavaScriptのコンパイラ、Babelに入門」を参照してみてください。Babelでのコンパイルは以下のように行います。
babel -o spread_operator.bundle.js spread_operator.js
そして出力されたspread_operator.bundle.jsをブラウザに読み込ませれば動作確認ができます。



スプレッド演算子とは

スプレッド演算子(Spread Operator)とは、...を用いた値の展開を行うオペレーターです。配列に対して使うことができます(後ほどオブジェクトの場合も説明します)。具体的には以下のように使います。

複数の引数を持つ関数を呼び出す際に、...dと引数に指定できる

function func1(a, b, c) {
    console.log('func1', a, b, c);
}
let d = [1, 2, 3];
func1(...d); // => func1 1 2 3

// 参考:ES5までのやり方だとapplyメソッドを使う
func1.apply(null, d);

配列の中に、...dを用いて配列を展開する

let d1 = [1, 2, 3];
let d2 = [0, ...d1, 4, 5];
console.log(d2); // => [ 0, 1, 2, 3, 4, 5 ]

分割代入で余った引数を...dで受け取る

let [a, b, ...d] = [1, 2, 3, 4, 5];
console.log(d); // => [ 3, 4, 5 ]

分割代入については「[ES6] 分割代入(Destructuring assignment)を使いこなす」をご参照ください。


配列のコピーを行う([...d]でコピーできる)

let d1 = [1, 2, 3];
let d2 = [...d1];
d2[1] = 10;
console.log('d1:', d1); // => [1, 2, 3] # 影響を受けない

// 参考:ES5までの場合には以下で配列コピーを行う
let d2 = d1.slice();
と、こんな感じで使うことができます。特に1つ目の関数への値の渡し方が非常に便利だなーと感じています。



オブジェクト版のスプレッド演算子

似たようなものでオブジェクトでも...を使うことができます。ただしこちらは仕様が未Fixのため、NodeJSなどでは使うことができず、以下のBabelコンパイルが必要です。
# オブジェクトのスプレッドオペレーターを使えるように変換する
babel --presets stage-1 -o spread_operator.bundle.js spread_operator.js
またstage-1のプリセットを使うために、npmインストールも行います。
$ npm install --save-dev babel-preset-stage-1


そして使い方ですが、オブジェクトのスプレッドオペレーターは以下のように使うことができます。

残りのプロパティを一気に受け付ける(...othresのところ)

let person = {
    firstName : 'Yohei',
    lastName  : 'Munesada',
    age       : 31,
    city      : 'yokohama',
    favs      : ['Ramen', 'Tennis']
};

const {
    firstName,
    lastName,
    ...others  // age、city、favsを持つオブジェクトになる
} = person;
console.log('others:', others); // => others: { age: 31, city: 'yokohama', favs: [ 'Ramen', 'Tennis' ] }

オブジェクト内への展開(同じく...othresのところ)

let other = { age: 31, city: 'yokohama', favs: [ 'Ramen', 'Tennis' ] }

let person = {
    firstName : 'Yuyu',
    ...others
};
console.log('person:', person);
/*
    person: { firstName: 'Yuyu',
      age: 31,
      city: 'yokohama',
      favs: [ 'Ramen', 'Tennis' ] }
*/
例えばmaterial-uiのレポジトリではstage-1のプリセットが使われていて、いい感じにコーディングされています(僕もよく使います)。



参考リンク

今回の機能を学ぶために以下のリンクを参照しました。ありがとうございます。

スプレッド演算子 - JavaScript | MDN

Spread Operator (...) (JavaScript) | Microsoft Developer Network

Stage 1 preset · Babel

sebmarkbage/ecmascript-rest-spread: Rest/Spread Properties for ECMAScript | Github



最後に

ECMAScript6(ES2015)には色々な機能があって楽しいですね。色々なオープンソースのコードを読んでいて、こんな使い方ができるのかーと発見が多いです。他にもES6について学んだことはブログに残していければと思います。

最後になりますが本ブログでは、フロントエンド・Go言語・Node.js・Python・Linux・開発関連・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。