CHAPTER 7 · 4 LESSONS · 52 問
関数をわたす
関数そのものを値として別の関数に渡す。配列の道具の中で起きていたことの正体を見る。
前の章で、配列の道具に「処理そのもの」を渡した。あれは何だったのか。この章でその正体を見にいくよ。
答えを先に言うと、JavaScript では関数も値のひとつだ。数値や文字列を変数に入れたり、引数として渡したりできるのと同じように、関数もそうできる。関数だけが特別な存在ではない、ということだね。
この考え方に慣れると、いろいろなことがつながって見えてくる。関数を変数に入れられる。関数を配列に入れられる。関数を引数として別の関数に渡せる。この最後のものが コールバック関数 と呼ばれるものだよ。「あとで呼び返してもらう関数」という意味だ。
なぜこんなことをするのか。処理の骨組みだけ決めておいて、中身は使う側に決めてもらうためだ。配列の道具がまさにそうだった。「配列を1件ずつ取り出して、何かをして、結果を集める」という骨組みは道具側が持っている。「何をするか」の部分だけを、使う側が関数として渡す。だから同じ道具が、合計にも変換にも絞り込みにも使える。
この分担のしかたは、コールバックに限らずプログラミング全体に出てくる考え方だよ。変わらない部分と変わる部分を分けて、変わる部分を外から差し込めるようにする。これができると、部品の使い回しがぐっと効くようになる。
もうひとつ、コールバックには「あとで呼ぶ」という時間の側面もある。ボタンが押されたときに呼ばれる関数、データが届いたときに呼ばれる関数。いつ呼ばれるかは今は分からないが、そのときが来たら呼んでほしいという渡し方だ。Web のプログラムはこの形だらけで、ボタンのクリックひとつ取ってもコールバックでできている。
読むときのコツをひとつ。コールバックが出てくるコードは、入れ子が深く見えて身構えてしまう。そういうときは、渡している関数をいったん別の場所に切り出して名前をつけてみるといい。array.filter(isAdult) のように書けば、やっていることが一目で分かる。慣れてきたら、その場に直接書く形も自然に読めるようになるよ。
つまずきやすいのは、関数を渡すのと、関数を呼んで結果を渡すのを取りちがえることだ。カッコを付けると呼び出しになり、その場で実行された結果が渡ってしまう。渡したいのは処理そのものなので、カッコは付けない。この1文字の違いで動きがまるで変わるので、意識しておこう。
この章はここまでの総仕上げでもある。関数・引数・戻り値・スコープが分かっていないと、コールバックは読めない。逆にここが腑に落ちれば、他人の書いた JavaScript がぐっと読めるようになるよ。
練習のしかたとしては、前の章の道具を自分で作ってみるのがいちばん効く。配列を1件ずつ処理する関数を、自分の手で書いてみるのだ。中で for を回して、渡された関数を1件ごとに呼ぶ。20行にも満たないコードだけれど、書き上がったとき「なるほどこうなっていたのか」と腑に落ちるはずだよ。
この考え方は、この先どの言語に進んでも出てくる。名前は違っても、「処理を値として渡す」という発想はどこにでもある。JavaScript でここを通っておくと、次に別の言語を触るときに理解が速いよ。
そしてここが、JavaScript コースの最後の章だ。ここまで来たあなたは、値を扱い、判断し、くり返し、まとめ、部品に分け、部品どうしを組み合わせる方法をひととおり手にしている。次は HTML と CSS で見た目を作り、いよいよ自分のアプリへ進んでいこう。
この章のレッスン
コールバック関数