JavaScriptのスプレッド構文(...)を理解する

本記事は 【JavaScript】スプレッド構文の便利な使い方まとめ の内容を理解するにあたり、内容をなぞりながら、わからなかった部分などに独自にメモを付け加えたものです。

スプレッド構文

... の事。

個々の値に展開する

配列を展開して処理する事ができる

console.log(Math.max(5,2,14,9)); // 14

// このように書き換えられる
const data = [5,2,14,9];
console.log(Math.max(...data)); // 14

ちなみに

console.log(Math.max(data)); // NaN

と違うのはそもそも Math.nax() は引数は配列で受け取らないので、展開し手渡す必要がある。
そのような場面で有効なのがスプレッド演算子(...)なのだと思う。

配列の複製

このように配列は複製できる。

const ary = ['Pen', 'Pineapple'];
const myAry = [...ary];

ただし...

const ary = ['Pen', 'Pineapple'];

// ケース1 : そのまま代入(こんな事をする必要はないと思うが...)
const myAry0 = ary;
// ケース2 : スプレッド演算子で代入
const myAry1 = [...ary];

// どちらも中身は同じになる
console.log(myAry0); // [ 'Pen', 'Pineapple' ]
console.log(myAry1); // [ 'Pen', 'Pineapple' ]

/*
ただし、スプレッド演算子で改めて作ったものは、値としては同じだが、
インスタンスが別なので、比較するとfalse が返ってくるので、
中の要素を比較したい場合はループして配列の要素をそれぞれ比較するか
jsonなどに変換して比較する必要がある
*/
console.log(ary === myAry0);    // true
console.log(ary === myAry1);    // false

「インスタンスが別」とは

let ary = ['Pen', 'Pineapple'];
let myAry0 = ary;
// myAry0 に 'Applepen' を代入する
myAry0[2] = 'Applepen';

// myAry0 は ['Pen', 'Pineapple', 'Applepen' ] になるが...
console.log(myAry0); 

// ary の方も ['Pen', 'Pineapple', 'Applepen' ] になる。
console.log(ary);

// これは参照しているインスタンスが「同じ」だから

個別の要素については以下のように参照は保たれます。

// オブジェクトを持つ配列fruitを作成
const fruits = [
  { 'banana': 100 },
  { 'cherry': 200 }
];

// fruitsをmyFruitsにスプレッド演算子を使って複製
const myFruits = [...fruits];

// 元の配列の値を操作
fruits["0"].banana = 300;
// fruitsを複製したmyFruitの値も変更される
console.log(myFruits); 

.push()で結合

// 以下の場合4つめの項目にdata2が配列のまま入る
let data1 = [1, 2, 3];
let data2 = ['d', 'e', 'f'];
data1.push(data2); 
console.log(data1); // [ 1, 2, 3, [ 'd', 'e', 'f' ] ]

// スプレッド演算子で展開して結合する場合
data1 = [1, 2, 3];
data2 = ['d', 'e', 'f'];
data1.push(...data2);
console.log(data1);    // [1,2,3,"d","e","f"]

.unshift() 逆の順番で結合

let data1 = [1, 2, 3];
let data2 = ['d', 'e', 'f'];
data1.unshift(...data2);
console.log(data1);   // [ 'd', 'e', 'f', 1, 2, 3 ]

配列を展開してマージする

let data1 = [1, 2, 3];
let data2 = ['d', 'e', 'f'];

const merged = ['あ', ...data1, 'い', ...data2, 'う'];
console.log(merged);  // [ 'あ', 1,  2,  3, 'い', 'd', 'e', 'f', 'う' ]

配列を分解する

let [a, b, ...other] = [1, 2, 3, 4, 5];

console.log(a);        // 1
console.log(b);        // 2
console.log(other);    // [3, 4, 5]

文字列を1文字ずつに分解して配列にする

const word = 'JavaScript';
const converted = [...word];

console.log(converted); // ["J","a","v","a","S","c","r","i","p","t" ]

文字列を1文字ずつに分解してループ処理

const word = 'Java';

// 一文字づつループ操作する。
[...word].forEach(c => console.log(c)); 

// 結果 ↓
// J
// a
// v
// a

// - 文字列を反転する
// 配列に変換し右から左へたたみ込む。
const reversed = [...word].reduceRight((p, c) => p + c); 
console.log(reversed); // avaJ

配列から重複を取り除く

Set オブジェクトは重複しないののだけ管理してくれる

const data = ['a', 'b', 'c', 'a', 'b', 'd'];
const dist = [...(new Set(data))];

console.log(dist);    // ["a","b","c","d"]

引数が可変でも定義できる

const sum = (...nums) => nums.reduce((p, c) => p + c);

console.log(sum(1, 2, 3, 4, 5));     // 15

NodeList や HtmlCollction に .filter() を掛ける

const elems = document.getElementByClassName('checkboxClassName');

// 取得した **NodeList** から、**checked** プロパティが **true** かつ **class** プロパティに **'foo'** が含まれているものを抽出します。
const filtered = [...elems].filter(el => el.checked && el.classList.contains('foo'));

チェックボックスをチェック、リストボックスをセレクトする

const setCheckBox = (name, ...values) => {
	// 引数でうけとったname属性の要素を取得
	const elems = document.getElementsByName(name);
	// ループしながら一個の要素 el に values で受け取った項目を含んでいたらチェックする
	elems.forEach(el => el.checked = values.includes(el.value));
}
// value が 'apple' 、'banana' のチェックボックスをチェックします。
setCheckBox('fruits', 'apple', 'banana');  

参考

投稿者プロフィール

kurudrive
名古屋のウェブ制作会社数社に10年程度務めた後、株式会社ベクトル設立。
企画・運営・コンサルティング〜WordPressを中心としたシステム開発まで幅広く携わる。
[ 著書 ]
・いちばんやさしいWordPressの教本(共著)
・現場でかならず使われているWordPressデザインのメソッド(共著)
[ 最近のWordPressコミュニティでの活動 ]
2018 WordCampOsaka セッションスピーカー
2017 WordCampKyoto セッションスピーカー
2016 WordCampTokyo LT
2016 WordCampKansai ハンズオン世話役
2015 WordCampTokyo セッションスピーカー
2015 WordCampKansai セッションスピーカー
2014 WordFesNagoya 実行委員 & セッションスピーカー
2013 WordCampTokyo セッションスピーカー(パネラー)
2013 WordFesNagoya 実行委員 & セッションスピーカー
2013 WordCrabFukui セッションスピーカー

Follow me!

シンプルでカスタマイズしやすいWordPressテーマ

Lightningは twitter Bootstrap ベースのシンプルでカスタマイズしやすいWordPressテーマです。
プラグイン VK All in One Expansion Unit とセットで使う事でビジネスサイトにもブログにも活用できます。