〽️ 「spread」が意味するものは? 〽️ 具体的な使いどころ。 〽️ 本質はオブジェクトの「複製」にあり。
JavaScriptコードの「?」をまとめたページはこちら⬆︎。
let array = ["a","b","c"]; console.log(「「1...array」」);
こんにちは、「ふ」です。
JavaScriptコードの「これって何?」、今回はこちら⬇︎。
let array = ["a","b","c"]; console.log(「「1...array」」);
配列やオブジェクトの前に「...」が付けられている、何をやっているのか?
〜これはスプレッド構文と呼ばれるもので、連続する要素の内容をまとめて記述することのできる、便利な「記述法」です。
スプレッド構文は「スプレッド演算子」と呼ばれることもありますが、「+」や「*」などの通常の演算子とは別物で、すこしばかり特殊な存在。
記事内ではスプレッド構文の使いどころとともに、その本質とメリットについて紹介していきます。
今回も内容を理解して、サンプルコードに「...」が出てきても動揺しないスキルを身につけましょう。
スプレッド構文(spread syntax)、「spread」は「展開」、「syntax」は「構文」という意味です。
「...」の後に与えられた要素の内容を、展開して記述することができます。試しに、配列でやってみましょう。
let array1 = ["りんご","みかん","バナナ"];
テキトーに配列を作りました。
これをスプレッド構文にして、console.logに渡してみます。
console.log(「「1...array1」」); 「「3>>りんご みかん バナナ」」
配列の中身が出力されました。
これは、⬇︎を記述したことになります。
console.log("りんご みかん バナナ");
spreadを使うと、1撃で記述できるので便利ですね。
spreadしたarray1は、「配列要素」としてではなく、「中身だけ」が渡されています。
array1そのものと、spreadしたもの。それぞれconsole.logに渡した場合を比較してみましょう。
console.log(array1); 「「3>>(3) ['りんご', 'みかん', 'バナナ']」」
array1をそのままconsole.logしてみました。
consoleには角括弧[ ]で囲まれた3つのテキストが出力されます。「配列」という、「意味を持った集合」として渡されていることが分かります。
console.log(「「1...array1」」); 「「3>>りんご みかん バナナ」」
一方spreadしたものを出力してみると、単なる3つのテキストが出力されました。この3つは ただの「中身」であって、集合としての意味を持っていません。
変数をそのまま渡した場合。
console.logには角括弧[ ]を含めた全体が渡されるため、「配列」として出力されます。
スプレッド構文として渡した場合は、連続要素の「中身」だけが渡されます。
console.logの立場からすると、単なる3つの文字列に過ぎません。そう考えると、「単なるコピペ作業」のようにも思えますが....
ところでこの構文が「spread(展開)」と名付けられているのは、何?
要素の集合をスプレッド構文で記述すると、その場所に適切な形で「展開」させて記述できるからです。ここが「単なるコピペ」とは違う、スプレッド構文のすぐれたところです。
「適切な形」。
ここまでの例では中身の渡し先はconsole.logでしたが、中身を配列に渡した場合にはちゃんと配列の要素として展開・記述してくれます。
次のセクションで具体的な使い方と挙動をみていきましょう。
スプレッド構文は色んな「連続する要素」に対して使うことができます。
配列の複製や要素の追加を行ってみましょう。
const fluit1 = ["りんご","みかん"];
配列「fluit1」を作りました。
const fluit2 = [「「1...fluit1」」]; console.log(fluit2); 「「3>>(2) ['りんご', 'みかん']」」
配列「fluit2」を作り、fluit1のスプレッドを渡すと..
複製されています。
const fluit3 = [...fluit1「「1,"バナナ"」」]; console.log(fluit3); 「「3>>(3) ['りんご', 'みかん', 'バナナ']」」
配列要素の追加です。
fluit1のスプレッドのあとに、追加する要素を直接記述。これで追加することができます。
const fluit4 = [「「1...fluit1」」, 「「1...fluit3」」]; console.log(fluit4); 「「3>>(5) ['りんご', 'みかん', 'りんご', 'みかん', 'バナナ']
2つの配列の結合。
fluit1とfluit3のスプレッドをカンマ「,」で区切って記述すると、配列が結合されたものが出来上がりました。
関数の引数にスプレッド構文を渡したバヤイ。
「第1引数には中身の1つ目、第2引数は中身の2つ目....」というように順番に割り当てられていきます。
function spray(value1,value2) { console.log(value1); console.log(value2); }
第1引数と第2引数をconsole.logする関数「spray」を作りました。
ここに、fluit4 [ 'りんご', 'みかん', 'りんご', 'みかん', 'バナナ' ] を渡してみます。
spray(「「1...fluit4」」); 「「3>>りんご」」 「「3>>みかん」」
第1引数と第2引数にそれぞれindex[0]と[1]が割り当てられ、出力されました。
引数は2つしかないため、index[2] 〜 [4] は無視されます。
文字列をspread形式で配列に渡すと、1文字ごとの配列にすることができます。
let fluit5 = "ぶどう"; let fluit6 = [...fluit5]; console.log(fluit6); 「「3>>(3) ['ぶ', 'ど', 'う']」」
split( )メソッドのようなことができるのですね。
オブジェクトについても配列と同じように、スプレッド構文を使って編集を行うことができます。
const obj1 = { bbapple:"赤", bborange:"橙" };
オブジェクト「obj1」を作りました。
const obj2 = {「「1 ...obj1」」 }; console.log(obj2); 「「3>> { apple: '赤', orange: '橙'}」」
obj2を作り、obj1のスプレッドを渡すと、複製することができます。
const obj3 = { ...obj1「「4,grape:"紫"」」 }; console.log(obj3); 「「3>> { apple: '赤', orange: '橙', grape: '紫'}
プロパティと値の追加も配列の時と同様、スプレッドに続いて直接内容を追加すると実現します。
const obj4 = { pine:"黄",melon:"緑"}; const obj5 = { 「「1...obj3」」,「「1...obj4 」」}; console.log(obj5); 「「3>> { apple: '赤', orange: '橙', grape: '紫', pine: '黄', melon: '緑'}
結合も簡単に ♪
スプレッド構文、使い勝手が良過ぎます。
みなさんも簡単なコードで試してみてくださいね。
前のセクションで配列やオブジェクトの「複製」を行ってみました。ときにこれは、スプレッド構文ならではの利点でもあります。
「ん? 複製であれば、普通の配列を入れた変数/定数を使ってできるのでは?」
と思うかもしれません。
それでははじめに、通常の配列記述だけを使って複製を試みます。
配列「menu1」を作りました。
let menu1 = ["ハンバーガー","ポテト","コーラ"];
このときコンピュータのメモリ内に [ "ハンバーガー","ポテト","コーラ" ] という配列が生成されます。
そして「menu1」という識別子。
ここには生成された配列そのものが代入されるわけではありません。
「menu1」には、
「あなたはここを呼び出してくださいよ〜」
という参照命令が代入されているのです。
変数「menu2」を作り、「menu1」を代入。
let menu2 = menu1;
すると、menu2にも同じ「参照命令」が渡されます。
menu1もmenu2も、メモリ内にある同一の配列を参照している状態です。メモリ内で配列が複製されている訳では決してありません。
menu2[2] = "ウーロン茶";
menu2のインデックス[2]を変更したとき。参照された配列の内容が書き換えられます。
そしてその後、menu1の[2]を呼び出してみます。
console.log(menu1[2]); 「「3>>ウーロン茶」」
menu1とmenu2はメモリ内の同一の配列を参照しているため、menu1のインデックス[2]を出力しても「ウーロン茶」となってしまいます。
配列の参照先が代入された変数そのものを操作しても、配列の実体は1つであるため「複製」はできていません。
スプレッド構文を利用すれば、配列の実体を複製することが可能です。
let menu1 = ["ハンバーガー","ポテト","コーラ"]; let menu3 = [「「1...menu1」」];
新たにmenu3という配列をつくり、そこにmenu1の内容をスプレッド構文で記述します。
このとき、渡されるのはmenu1の中身である3つの文字列です。この3つの文字列は配列としての意味を持っていないので、参照命令が渡されるわけではありません。
ただ単に3つの文字列がmenu3の[ ]の中に適正に展開(spread)されます。
そのためコンピュータは「新規配列」だと認識し、メモリ内に新たな配列が生成されることになります。
つまり「配列の複製」が実現します。
試しにmenu3のインデックス[2]を変更し、menu1のものと比べてみましょう。
menu3[2] = "ファンタ"; console.log(menu1[2]); 「「3>>コーラ」」 console.log(menu3[2]); 「「3>>ファンタ」」
配列menu1の状態はそのままに、配列menu3の内容を変更することができました。
メモリ内で配列が複製できていることが分かります。
連続要素の本質的な「複製」。これがスプレッド構文の存在意義です。
配列を例に紹介しましたが、オブジェクトを扱う場合にも同じことが言えます。
もとのオブジェクトを残しつつ「複製」したい場合は、スプレッド構文を使って作成しましょう。
最後までお読みくださり、ありがとうございます。
スプレッド構文。連続する要素の中身だけを複製し、単なるペーストではなくその場所にあった形式で展開してくれる 〜という非常に便利なものでした。
これはもう、サンプルコードの解読にとどまらず、自分でもどんどん使っていきたい構文ですね!皆さんもぜひ活用してください。
let array = [ "では","また","お会いしましょう" ];
...array ♪
JavaScript、乱数の範囲や重複を指定〜Math.random使い方。
2021.11.17
整数/範囲/重複の有無を自在にあやつろう。
JavaScriptの矢印「=>」〜これはアロー関数というものです。
2022.01.09
使い方とメリットについて解説。
ブログのクリックをGoogle Analyticsで計測。
2021.11.30
新たなツールは導入せずともOK。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。