定義と使用方
スプレッド構文(Spread Syntax、展開構文)とは、値(value)として反復可能なオブジェクト(配列、文字列、DOMコレクションなど)の要素を簡単に個別に展開して列挙する(spread)JavaScriptの構文です。
スプレッド構文(Spread Syntax)は「展開構文」または「スプレッド演算子」とも呼ばれます。
スプレッド構文(Spread Syntax)を使用すると、配列やオブジェクトの要素を簡単にコピーしたり結合したりすることができます。
複雑なコードをより短く、シンプルに記述できるため便利です。
構文の形式
スプレッド構文は非常にシンプルです。...
(ドット3つ)の後に、値(value)として反復可能なオブジェクト(配列、文字列、DOMコレクションなど)を続けて記述します。
基本的な構文の例を通して見ていきましょう。
/* 配列 */
const arr = [1, 2, 3];
console.log(...arr); // 出力: 1 2 3
/* 文字列 */
const str = "Hello World";
console.log(...str); // 出力: "H e l l o W o r l d"
/* DOMコレクション */
const items = document.querySelectorAll(".item"); // NodeListを返す
const itemsArray = [...items]; // スプレッド構文を使って配列に変換
// これで配列メソッドを使用可能
itemsArray.forEach(item => {
console.log(item.textContent);
});
基本の例
次の例は、スプレッド構文を使用して2つの配列を簡単に結合する方法を示しています。例のようにスプレッド構文を使用すると、配列やオブジェクトを簡単にコピーしたり結合したりできるため、複雑なコードを短くシンプルに記述することが可能です。
const arr1 = [1, 2];
const arr2 = [3, 4];
const mergedArr = [...arr1, ...arr2]; // 配列の結合
console.log(mergedArr); // [1, 2, 3, 4]
スプレッド構文を使用できる対象
スプレッド構文は、値(value)として反復可能なオブジェクトにのみ使用できます。
値(value)として反復可能なオブジェクト、つまりスプレッド構文を使用できる対象は次の通りです。
- 配列:配列の各要素
- 文字列:文字列の各文字
- DOMコレクションオブジェクト(
NodeList
、HTMLCollection
):各要素オブジェクト Map
オブジェクト:各キーと値のペアSet
オブジェクト:各値Function
のarguments
オブジェクト:各引数- Iteration Protocolsが適用されたカスタムオブジェクト
一般的なオブジェクト(Plain objects)でのスプレッド構文の使用
オブジェクトリテラルなどで作成した一般的なオブジェクト(plain objects)は、プロパティ(key)としては反復可能ですが、値(value)としては反復できません。
つまり、スプレッド構文を直接使用できる対象ではないということです。しかし、ECMAScript 2018(ES9)以降では、オブジェクトリテラル内でスプレッド構文を使用して、他のオブジェクトリテラルのプロパティを展開し、結合またはコピーすることが可能です。
活用例
例を通して、値(value)として反復可能なオブジェクトにスプレッド構文を使用する活用方法を見ていきましょう。
配列の拡張
スプレッド構文を使用すると、配列の要素を結合したり拡張したりするのが非常に便利です。既存の配列の要素を新しい配列にコピーし、新しい要素を追加したり、別の配列を結合したりすることができます。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// 2つの配列を結合
const mergedArray = [...arr1, ...arr2];
console.log(mergedArray); // 出力: [1, 2, 3, 4, 5, 6]
// 新しい要素を追加しながら配列を拡張
const extendedArray = [...arr1, 4, 5];
console.log(extendedArray); // 出力: [1, 2, 3, 4, 5]
関数呼び出し時の引数の渡し方
関数を呼び出す際に、スプレッド構文を使用して配列や引数リストを渡すことができます。これにより、関数が可変引数を受け取る場合でも、配列から個別の引数として渡すことが可能です。
function sum(a, b, c) {
return (a + b + c);
}
const numbers = [1, 2, 3];
const result = sum(...numbers); // sum(1, 2, 3)と同じ結果を返す
console.log(result); // 出力: 6
NodeList
でDOMを操作する
スプレッド構文を使用すると、初心者でもNodeList
のようなDOMオブジェクトをより簡単に扱うことができます。NodeList
はDOM要素のコレクションで、配列に似た構造を持っていますが、配列メソッドを直接使用できない疑似配列オブジェクトです。
スプレッド構文を使用すると、NodeList
を配列に変換したり、他の配列と結合したりすることが簡単になります。
// HTMLドキュメント内の .item クラスを持つすべての要素を選択
const items = document.querySelectorAll(".item"); // NodeListを返す
// スプレッド構文を使用してNodeListを配列に変換
const itemsArray = [...items];
// itemsArrayは配列に変換されているため、配列メソッドを使用可能
itemsArray.forEach(item => {
console.log(item.textContent); // 各 .item 要素のテキスト内容を出力
});
// 他の配列と結合
const newItems = ["New Item 1", "New Item 2"];
const allItems = [...itemsArray, ...newItems]; // 既存のNodeListと新しい配列を結合
console.log(allItems); // NodeList + 新しい配列
注意点
スプレッド構文を使用する際には、いくつかの注意点があります。
スプレッド構文自体を変数に代入することは禁止
スプレッド構文は、オペランドを演算する演算子(operator)ではありません。
スプレッド構文は、一般的に「スプレッド演算子」とも呼ばれますが、厳密に言うと誤った表現です。演算子はオペランドを演算して値として表現できる必要があります。そのため、スプレッド構文を「スプレッド演算子」と呼ぶことはできず、文脈に応じて使用可能な構文です。
const items = ...[1, 2, 3, 4]; // Uncaught SyntaxError
オブジェクトリテラルでのスプレッド構文の使用
スプレッド構文を使用できる対象で説明した通り、オブジェクトリテラルは値(value)として反復可能なオブジェクトではなく、プロパティ(key)として反復可能なオブジェクトです。つまり、スプレッド構文を直接使用できる対象ではないということです。
しかし、ECMAScript 2018(ES9)以降では、オブジェクトリテラル内でスプレッド構文を使用して、他のオブジェクトリテラルのプロパティを展開し、結合またはコピーすることが可能です。
スプレッド構文を直接使用できる対象ではない
次の例は、オブジェクトリテラルがスプレッド構文を直接使用できないことを示す代表的な例です。
const obj = {
a: 1,
b: 2,
c: 3
}
console.log(...obj); // Uncaught TypeError
オブジェクトリテラル内で他のオブジェクトリテラルのプロパティをコピーまたは結合
ECMAScript 2018(ES9)以降では、オブジェクトリテラル内でスプレッド構文を使用して、他のオブジェクトリテラルのプロパティを展開し、結合またはコピーすることが可能です。
const obj1 = {
x: 1,
y: 2
}
const obj2 = {
z: 3
}
// オブジェクトの結合
const mergedObj = {...obj1, ...obj2};
console.log(mergedObj); // { x: 1, y: 2, z: 3 }
ブラウザ互換性
構文 |
デスクトップ Chrome
|
デスクトップデスクトップ Edge
|
デスクトップ Firefox
|
Safari
|
Node.js
|
---|---|---|---|---|---|
Spread syntax (...) | 46 | 12 | 16 | 8 | 5 |
オブジェクトリテラル内で別のオブジェクトリテラルのプロパティをコピーまたはマージ | 60 | 79 | 55 | 11.1 | 8.3 |