👋

スプレッド構文と残余引数

2022/12/22に公開

この2つ、見た目同じなのに、反対の挙動するから混乱してました!
仮引数の位置に「…」があったら、残余引数を疑ってみましょう。

スプレッド構文

  • 名前のまんま「spread」なので、「広げる」とか「ばらす」イメージ。
  • スプレッド演算子のオペランドにあるものをばらす。つまり配列やハッシュ構造を展開したり、文字列の場合はイテラブルなので、すべての文字を1つの要素にマッピングしてくれます。
これは何を返しますか?
[..."Yuri"];
A: ["Y", "u", "r", "i"] 正解
B: ["Yuri"]
C: [[], "Yuri"]
D: [["Y", "u", "r", "i"]]
  • 配列やオブジェクトの要素のクローンを作成したい時に用いたりします。
const foo = [1, 2];
// スプレッド演算子による配列のクローン
const bar = [...foo];
console.log(bar); // [1, 2]
// 配列をマージ
const hoge = [...foo, ...bar]; // => [1, 2, 1, 2]
// 要素を追加して新しい配列を生成
const baz = [...foo, 3, 4]; // => [1, 2, 3, 4]

残余引数

  • 仮引数に…の接頭辞を付けると、その引数を配列の中に格納できる。引数が多すぎる場合とかに、こうすることで残った引数を一つの配列の中にまとめてくれる。
  • この問題の解説にスプレッド構文って書いてあったから、必死にスプレッド構文のmdn読んでたんですけど「書いてあることはわかるけど何でこれ答えなの?」状態でした。何故ならこれは見た目がよく似た「残余引数」だからです。
  • スプレッド構文は挙動が「展開」だけど残余引数は「集約」になってて、見た目同じなのに逆の動きしてて紛らわしい
function myFun(a,  b, ...manyMoreArgs) {
  console.log("a", a)
  console.log("b", b)
  console.log("manyMoreArgs", manyMoreArgs)
}

myFun("one", "two", "three", "four", "five", "six")

// コンソール出力:
// a, one
// b, two
// manyMoreArgs, ["three", "four", "five", "six"]
問題 **何が出力されるでしょうか?**
function getAge(...args) {
  console.log(typeof args);
}
getAge(21);

- A: `"number"`
- B: `"array"`
- C: `"object"`  正解 typeofだとプリミティブ以外全てオブジェクトと判定されるので、配列だけどobject
- D: `"NaN"`

参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters

https://github.com/lydiahallie/javascript-questions/blob/master/ja-JA/README-ja_JA.md

Discussion