カメリアの記事

意味があることやないことを綴ります

JavaScript の即時関数ってなんだ

即時関数という語を知りました。なんだそれ。とりあえずググって「即時関数の使い方と構造について」という記事を流し読み。ざっくり「即時実行される関数の書き方」というような印象。下のような書き方になります。

(function() {
  // 処理
})()

ショートハンドで下のようにも書けます。

(() => {
  // 処理
})()

ここまで来るとどこかで見たような記述です。下のような場合です。

window.addEventListener("click", () => {
  // 処理
})

構造上、メソッド addEventLinstener() に引数 "click" が渡されていますが、そこんところをスルーして書くと下のようになります。

(() => {
  // 処理
})

なんだあれと同じかぁ、と思ったわけですが、これじゃ実行されない! そう、前の記述では addEventListener() が実行してくれていたわけですが、この記述では実行してくれる人がいないのです。

そもそも即時関数のお尻の () ってなんだ。こいつが実行しているのか。実際この括弧を付けると実行されます。そういえばお尻に括弧というと下のような記述で重要な役割を果たします。

let something = () => {
  // 処理
}

これで下のようにするとエラーは出ませんが実行もされません。

let something = () => {
  // 処理
}
something

そう、ここで括弧の出番です。括弧を付けると実行されるのです。

let something = () => {
  // 処理
}
something()

お尻の括弧が実行していた! ということは……?

let something = function() {
  // 処理
}()

おお、これだと実行されますね。ただちょっと不可解なことがあって下のようにショートハンドで書くとエラーが出るということです。

let something = () => {
  // 処理
}()

うーん、よく分からない。教えて偉い人。だけど関数本体を括弧でくくると正常に動作します。下のような感じです。

let something = (() => {
  // 処理
})()

どうも関数本体をくくった括弧には何か意味があるようです。詳しい人ならきっと知っているでしょう。括弧はなんだか意味深ですからね。この話はここまでにしましょう。だって分からないんだもん。

さて、こうなってくると普通の即時関数と変わらない様相を呈してきました。 let something なんていらないんです。

(() => {
  // 処理
})()

そういうわけで関数名のお尻に付けるのと同じような括弧なんですが、関数と同じように引数を与えることができるようです。

((a, b) => {
  console.log(a + b)
})(1, 2)

へぇ。なんか普通の関数と何が違うんだよ、という気がしてきます。冒頭で紹介した記事「即時関数の使い方と構造について」ではグローバル変数に影響を与えずに書けるのがすげぇんだよ、という話だったのですが、それは普通の関数も同じです。そんな「即時関数」なんて特別に名前を与えるほどの意味があるんでしょうか。僕としては下のような記述のショートハンドという感覚で受け止めています。

something()
function something() {
  // 処理
}

でも僕より次元の違う頭脳を持った ECMA の皆さんが考え出した方法ですからもっと深い意味があるのでしょう。その JavaScript の深淵を探るために僕は初めて JavaScript の書籍を購入しました。

深淵をのぞくとき、深淵もまたあなたをのぞいているのだ。

さて、僕自身が JavaScript にならないよう注意しながら読んでみることにします。