CHAPTER 8 · 6 LESSONS · 78 問

今どきの書き方

分割代入・スプレッド・`?.`。他人のコードでいちばん先に出会う、短く書くための記号たち。

ここからは必修ではない章だよ。入門としてはここまでで足りている。それでも足すのは、この章の書き方を知らないと他人のコードが記号として読めないからだ。意味が分からないのではなく、そもそも何をしている行なのか見当がつかない、という詰まり方をする。

最初に覚えるのは for...of だ。配列を1件ずつ取り出すくり返しで、for (const fruit of fruits) { ... } と書く。章2で書いた for と同じことをするのだけれど、番号を自分で管理しなくていいi = 0 から始めて length まで増やして fruits[i] で取り出す、という定型がまるごと消える。番号の書きまちがいで起きる事故も一緒に消えるよ。

次が 分割代入。オブジェクトから必要な項目だけを取り出して、いっぺんに変数にする書き方だ。const name = user.name; を何行も並べるかわりに、const { name, age } = user; と1行で書ける。配列にも同じことができて、const [first, second] = ranking; のように順番で取り出せる。

これは「短く書けて便利」以上の意味を持っている。関数の引数でそのまま使えるからだ。オブジェクトを受け取る関数の引数に分割代入を書くと、中で何を使うのかが関数の見出しに出る。現場のコードでは、この形がとてもよく出てくるよ。

そして スプレッド... という3つの点。配列やオブジェクトをその場で広げる[...fruits, "もも"] と書けば、元の配列の中身を全部並べたうえに1つ足した新しい配列ができる。元は変わらない。ここが大事なところで、push のように元を書きかえるのではなく、新しいものを作って返す書き方になる。

同じ ... を関数の引数側に書くと、今度は逆にいくつでも受け取るという意味になる。残余引数と呼ばれる書き方だよ。広げるのと集めるのが同じ記号なのは最初ややこしいけれど、「値の側に書けば広げる、受け取る側に書けば集める」と覚えておけばいい。

最後が オプショナルチェーン?. だ。無いかもしれない項目をたどるときに使う。user.address.city は、address が無いとその場でエラーになってプログラムが止まってしまう。user.address?.city と書いておくと、無いときは止まらずに undefined が返る。

これは「エラーを握りつぶす道具」ではないよ。無いことがありうると分かっている場所にだけ書く。どこにでも ?. を付けると、本当は在るはずのものが無かったときにも黙って進んでしまい、原因の分からない不具合になる。使いどころを選ぶ道具だ。

この章の書き方は、どれもやっていること自体は前の章までで書けるものばかりだ。分割代入は代入の並べ書きだし、スプレッドはループで詰め直すのと同じ。だから「新しいことができるようになる章」ではなく、同じことを短く、まちがえにくく書けるようになる章だと思ってほしい。

読めるようになることが、まず第一の目標だよ。書けるようになるのはそのあとでいい。

この章のレッスン

番号を使わずくり返す

  1. 80番号を使わずくり返すfor (const fruit of fruits) の形で、番号を管理せずに配列を1件ずつ取り出そう。 問題へ

必要なものだけ取り出す

  1. 81オブジェクトから取り出すconst { name, age } = user; の形で、必要な項目だけをいっぺんに変数にしよう。 問題へ
  2. 82配列から取り出すconst [first, second] = ranking; の形で、配列の中身を前から順に変数にしよう。 問題へ

まとめて広げる・まとめて受け取る

  1. 83まとめて広げる[...fruits, "もも"] の形で、元をそのままにした新しい配列やオブジェクトを作ろう。 問題へ
  2. 84いくつでも受け取る引数function total(...numbers) {} の形で、引数を何個でも受け取って配列としてあつかおう。 問題へ

無いかもしれない値をたどる

  1. 85無いかもしれない項目をたどる?. を使って、無いかもしれない項目の先を止まらずにたどれるようにしよう。 問題へ

つぎは「キーと集合で持つ」。Map で好きなキーの組を持ち、Set で重複しない集まりを作る。配列とオブジェクトの次の入れもの。