【すぷれっどこうぶん】

スプレッド構文 とは?

最終更新:
💡 ドット3つで、中身を新しい場所へ広げる

JavaScriptで...を使い、配列などの値を要素や関数の引数へ展開する構文。オブジェクト内では自身の列挙可能なプロパティを新しいオブジェクトへ追加する。コピーは浅く、入れ子のオブジェクトは共有される。同じ...を使うレスト構文とは役割が異なる。

📌 このページのポイント
スプレッド構文:...で中身を広げるa = [1, 2]元の配列[...a, 3][1, 2, 3] を作る浅いコピー:入れ子の値は共有元のオブジェクトコピー同じ入れ子の値レストは「まとめる」、スプレッドは「広げる」だよ
配列の展開と、オブジェクトの浅いコピーの例。新しい外側の入れ物でも、入れ子のオブジェクトは共有されます。
ひよこ ひよこ
配列を、どう広げるの?
ペンギン先生 ペンギン先生
たとえばa=[1,2]、b=[3,4]なら、[...a, ...b]で[1,2,3,4]という新しい配列を作れるよ。元の配列の要素を順番に展開する書き方なんだ。関数でもMath.max(...a)のように、配列の値を個々の引数として渡せる。
ひよこ ひよこ
オブジェクトも、そのまま広げられる?
ペンギン先生 ペンギン先生
{...user, name: '新しい名前'}なら、user自身の列挙可能なプロパティを追加し、nameを後の値で上書きするよ。同じ名前は後に指定した値が使われる。ただし配列や引数への展開は反復可能な値が必要なので、普通のオブジェクトを[...user]と書けばよいわけではないんだ。
ひよこ ひよこ
コピーしたら、中のデータも別物?
ペンギン先生 ペンギン先生
浅いコピーなので、入れ子のオブジェクトは参照が共有されるよ。user={profile:{name:'A'}}からcopy={...user}を作り、copy.profile.nameを変えるとuser側にも影響する。外側の入れ物は新しくても、中まで独立していないんだ。深いコピーには、データの型などに合う方法を選ぼう。
ひよこ ひよこ
レスト構文も...だけど、どう違う?
ペンギン先生 ペンギン先生
スプレッドは広げ、レストは残りをまとめるよ。const [first, ...rest]=[1,2,3]なら、firstに1、restに[2,3]が入る。これは配列の分割代入のレストで、関数のレストパラメーターそのものではない。function f(...args)のような引数のまとめ方もあるね。
ひよこ ひよこ
大きなデータにも、いつでも使える?
ペンギン先生 ペンギン先生
新しい配列などを作るので、繰り返し大きなデータをコピーすると費用がかかるよ。また関数の引数へ大量に展開すると、エンジンの引数数の上限に達する場合がある。別の書き方が必ず速いとは決めず、必要な処理とデータで測って判断しよう。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「スプレッド構文」って出てきたら「...で中身を新しい場所へ広げるJavaScriptの書き方」と思えばだいたいOK!
📖 おまけ:英語の意味
「Spread syntax」 = 広げる構文
💬 spreadは広げるという意味。JavaScriptでは、配列・関数呼び出し・オブジェクト内で展開の仕方が異なるよ。

参考資料

← 用語集にもどる