【JavaScript】 コールバックに関数を指定すると実行されてしまう理由
更新日:2020/06/30
僕がJavaScriptを使いだしたころ、コールバック関数で少し悩んだことがある。
ネットではコールバック関数として無名関数が使用されていることがほとんどだが、20年以上前のプログラマな僕には少し気持ち悪く感じた。
だから外で関数を定義して、コールバック関数として指定した。
ところがうまく動かない。
すぐに理由がわかったのだが、今回は今一度理由を整理してみようと思う。
無名関数は動作する
"aaa"というIDを持つ要素があるという前提で次のコードを実行すると、「step 1:」「step 2:」とコンソールに表示され、要素をクリックすると「step 3:」と表示されるはず。
無名関数をコールバックに指定
$(function(){
console.log("step1:");
$("#aaa").on("click",function(event){
console.log("step3:");
});
console.log("step2:");
});
実行すると
実行結果:Firefox 開発ツールコンソール
step 1: step 2: step 3:
想定通りに動作した。
外で定義するとうまくいかない
引数の中に、やたらと長いコードが入っているなんて気持ち悪い!
そう感じたので、外で関数を定義してコールバックに指定してみた。
外で定義した関数をコールバックに指定
$(function(){
functionstep3(event){
console.log("step3:");
}
console.log("step1:");
$("#aaa").on("click", step3( event ) );
console.log("step2:");
});
実行すると…
実行結果:Firefox 開発ツールコンソール
step 1: step 3: step 2:
step3が先に実行されている?
しかも、"aaa"をクリックしたら反応がない。
なぜ?
関数名の後に()を付けると実行されるから
関数名の後に()をつけると、その関数は実行される。
そして関数で返した結果が、コールバックとして渡される。
上の関数は何も返していないのだから、要素をクリックしても何も実行されない。
考えてみれば当たり前のことだった。
無名関数という、なんだか気持ち悪い書き方から逃れたい一心で、当時に僕は冷静ではなかったようだ。
今は無名関数に慣れたので、間違えないようになりました。
無名関数を使わない書き方
では無名関数を使わないで、コールバックを指定するにはどうすればいいのか。
無名関数で囲む
当時実施したのが次のコード。
無名関数で囲む
$("#aaa").on("click",function(event){
step3(event);
});
無名関数使ってます…
当時の僕は、これで解決でした。
関数内で無名関数を返す
関数の実行結果として関数を返してあげれば、コールバックとして渡せる。
無名関数を返す
function step3(){
return function(event){
console.log( "step 3:");
}
}
$("#aaa").on("click",step3());
()をつけなければいい
そもそも()を付けないだけでいい。
()をつけない
function step3(event){
console.log( "step 3:");
}
$("#aaa").on("click",step3);
この結論に至るまで、1年かかりました。
まとめ
コールバック関数として関数名に()を付けたものを指定すると実行されてしまうのは、今になっては当たり前の知識です。
しかし見様見真似でコードを書いてた当時の僕は、何が何だかわかりませんでした。
更新日:2020/06/30
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。