スプレッド演算子、レストパラメーター、分割代入

■スプレッド演算子

スプレッド演算子(...)は、配列の全ての値を一括で「展開」できる、という機能である。

push()について復習。配列やオブジェクトは「参照型」。値そのものではなく、値への参照を持っている。参照先のアドレスが変わらなければ、メモリの中身である配列やオブジェクトの中身を変更することができる。

よって、以下の例で、push()を使って、activeHobbiesに配列を追加するとしたら、

const hobbies = ["Spotrs", "Viking", "Razicon"];
const activeHobbies = ["Hiking"];

activeHobbies.push(hobbies[0], hobbies[1], hobbies[1]);

console.log(activeHobbies);
>>>['Hiking', 'Spotrs', 'Viking', 'Viking']

となる。

これを、スプレッド演算子(...)を利用すると、

const hobbies = ["Spotrs", "Viking", "Razicon"];
const activeHobbies = ["Hiking", ...hobbies];

console.log(activeHobbies);
>>>['Hiking', 'Spotrs', 'Viking', 'Viking']

と記述量が大きく減る。

スプレッド演算子(...)は、配列だけでなく、オブジェクトにも使える。

const person ={
    name: "shingo",
    age: 46
}
const person2 = {
    ...person
}

console.log(person);
console.log(person2);
>>>{name: 'shingo', age: 46}
>>>{name: 'shingo', age: 46}

こうすることで、簡単にオブジェクトも中身をそのまま複製できる。

■レストパラメーター(残余引数=残りのパラメーター)

今までは、あらかじめ「決まった数の引数」を受け取る関数を書いてきたが、「任意の引数」を受け取れるようにするにはどうしたら良いか?

そこで活躍するのが、レストパラメーターである。

例えば

const add = () => {

}

const addedNumbers = add(1, 7, 89, 4, 73);
console.log(addedNumbers);

このような任意のパラメーターを受け取る関数を考える時、どのようにすれば良いか?

そこで活躍するのがスプレッド演算子(...)。スプレッド演算子は、パラメーターを渡すときだけでなく、受け取る時にも使うことができる。

const add = (...numbers) => {
}

このようにして、受け取りたい値を配列にして渡すことができる。配列名は任意で大丈夫。

この関数に渡されたパラメーターが、全て一つの配列にマージされて、一つの関数に渡される。

つまり、「1, 7, 89, 4, 73」が[1, 7, 89, 4, 73]として渡されて、... で展開される、という流れになる。

さらに、typescriptの場合は

const add = (...numbers: number[]) => {

}

とnumberの配列と型を指定する。

これで、numbersを数字の配列として扱うことができる、という流れである。

関数の中身を考える。合計値を計算することを考える。

一つはforを使い、中身をループさせて合計するやり方。

もう一つはreduce()を使って、配列の中身を何らかの一つの値にするやり方。

const add = (...numbers: number[]) => {
    numbers.reduce(() = {}, 0)
}

reduceの一つ目の関数は、計算を行う関数、二つ目は初期値。

これを、accumulator(蓄積した結果)とcurrentValue(現在の値)という引数を使って、計算結果を返す。

const add = (...numbers: number[]) => {
    return numbers.reduce((accumulator, currentValue) => {
        return accumulator + currentValue;
    }, 0)
}
const addedNumbers = add(1, 7, 89, 4, 73);
console.log(addedNumbers);

これが「レストパラメーター」である。

今回は「任意の引数」を受け取る例だったが、決まった数の引数であれば、タプル型と組み合わせて使うと効果的。

例えばこのように。

const add = (...numbers: [number, number, number]) => {
    〜略〜
}

■分割代入(デストラクチャリング)

ここでも、スプレッド演算子(...)が活躍。

配列の分割代入は以下になる。

const hobbies = ["Spotrs", "Viking", "Razicon", "Cooking", "Racing"];
const [hobby1, hobby2, ...restHobbies] = hobbies;

console.log(hobby1)
console.log(hobby2)
console.log(...restHobbies)
>>>Spotrs
>>>Viking
>>>Razicon Cooking Racing

と、分割できる。

次はオブジェクト。

const person = {
    firstName: "shingo",
    age: 46
}
const {firstName, age} = person;

console.log(firstName);
console.log(typeof(firstName));
>>>shingo
>>>string

と出力できる。

このことは、オブジェクトを変数(この場合はconst<定数>)に分割して格納することができる、ということを示している。

また、名前を変更できる。

const {firstName:changeName, age} = person;

このようにすることで、firstNameというconst(定数)名から、changeNameという定数名に変更できる。