スプレッド構文を使うと、関数呼び出しでは 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 = [0, 1, 2];
myFunction.apply(null, args);

スプレッド構文を使うと、上のコードは次のように書けます。

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);

スプレッド構文は、引数の何番目でも使えます。また、複数回使えます。

function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);

new 演算子と併用する

コンストラクタを new 演算子で呼ぶとき、 引数リストを Array で指定するために apply を使うことはできません。Function.prototype.apply はコンストラクタを関数として呼び出してしまうからです。

スプレッド構文を使えば、Array の要素をコンストラクタの引数として簡単に指定できます。

var dateFields = [1970, 0, 1];  // 1 Jan 1970
var d = new Date(...dateFields);

スプレッド構文を使わずに同じ結果を得るには、専用の関数を使う間接的な手段を取らざるをえません。

function applyAndNew(constructor, args) {
   function partial () {
      return constructor.apply(this, args);
   };
   if (typeof constructor.prototype === "object") {
      partial.prototype = Object.create(constructor.prototype);
   }
   return partial;
}


function myConstructor () {
   console.log("arguments.length: " + arguments.length);
   console.log(arguments);
   this.prop1="val1";
   this.prop2="val2";
};

var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments);
// (internal log of myConstructor):           arguments.length: 6
// (internal log of myConstructor):           ["hi", "how", "are", "you", "mr", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}

 

Array リテラルで使う

Array リテラルでスプレッド構文を使うと、すでにある Array を一部とする新しい配列を簡単に作れます。

var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes']; 
// ["head", "shoulders", "knees", "and", "toes"]

関数の引数と同様に、... は Array リテラルのどこでも、何回でも使えます。

スプレッド構文を使わない場合、Array リテラルだけでは不十分で、pushspliceconcat などを使うコードを書かなければなりません。

Array を複製する

var arr = [1, 2, 3];
var arr2 = [...arr]; // arr.slice() のような動きです
arr2.push(4); 

// arr2 は [1, 2, 3, 4] になります
// arr は変更されません

注意:コピーは 1 段階の深さで行われます。そのため、次の例のような多次元配列のようなオブジェクトをコピーする場合には適さないでしょう。Object.assign() についても同じことが言えます。

var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// a は影響を受けています: [[], [2], [3]]

Array を連結する

Array の連結には Array.concat がよく使われます。

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// arr1 の後ろに arr2 を連結した新しい配列をつくる
arr1 = arr1.concat(arr2);
// [0, 1, 2, 3, 4, 5]

スプレッド構文を使うと、次のように書けます。

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];
// [0, 1, 2, 3, 4, 5]

 

 

Object リテラルで使う

Rest/Spread Properties for ECMAScript proposal (stage 4) では、Object リテラルでのスプレッド構文が追加されています。スプレッド構文の対象となるオブジェクトの列挙可能なプロパティを、新しいオブジェクトにコピーします。

prototype を除いた浅いコピーの作成や、マージしたオブジェクトの作成が Object.assign() を使うよりも短いコードで書けます。

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

 

iterable オブジェクトで使えます

Object リテラルで使う場合を除き、スプレッド構文は iterable オブジェクトに対して使えます。iterable でないオブジェクトでは、TypeError 例外となります。

var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable

大量の値を展開する場合

JavaScript エンジンには、引数の個数に上限があります。関数呼び出しでのスプレッド構文では、引数の個数がその上限を超えてしまう可能性に留意してください。詳細は apply() のページを参照してください。

レスト構文(レストパラメータ)

レスト構文はスプレッド構文と全く同じ見た目をしていますが、Array や Object の分割代入に使われます。こちらはスプレッド構文とは逆の働きといえます: スプレッド構文が要素を展開するのに対して、レスト構文は複数の要素を集約して 1 つのオブジェクトにします。レスト構文 のページを参照してください。

仕様

仕様 ステータス コメント
ECMAScript 2015 (6th Edition, ECMA-262) 標準 Defined in several sections of the specification: Array Initializer, Argument Lists
ECMAScript Latest Draft (ECMA-262) ドラフト No changes.
ECMAScript Latest Draft (ECMA-262) ドラフト Defined in Object Initializer

ブラウザ互換性

機能ChromeEdgeFirefoxInternet ExplorerOperaSafari
Spread in array literals461216 なし378
Spread in function calls461227 なし378
Spread in destructuring49 なし34 なし37 ?
Spread in object literals60 なし55 なし ? なし
機能Android webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Spread in array literals464612163785.0
Spread in function calls464612273785.0
Spread in destructuring4949 なし3437 ?5.0
Spread in object literals6060 なし55 ? なし なし

関連情報

ドキュメントのタグと貢献者

このページの貢献者: kei-itof
最終更新者: kei-itof,