JavaScript の即時関数を改めて理解した

上の記事の「大枠」の章がとても分かりやすかった。

即時関数とは

その場で実行できる JavaScript の関数の一種。

(function() {
  // ココにコードを書く
  alert("Hoge Fuga");
})();

こういうヤツ。

構文は分かっていたし、

(function($) {
  // コード
})(jQuery);

こんな風に引数を渡せたりすることも知っていたけど、上の記事でもう少し理解が深まった次第。

まずは関数の書き方を見返す

定義されている関数 (メソッド) を呼び出して使うとき、update() のように、カッコを付けて表現する。引数がある場合は update(name) のように書いたりするだろう。

コレに対して、関数の定義自体は、以下のように行う。

// 関数宣言
function update(name) {
  // 処理
}

// 関数式 (関数リテラルを変数に代入する)
var delete = function(name) {
  // 処理
};

関数宣言の方は巻き上げ (ホイスト) と呼ばれる特徴があり、関数宣言が登場するより手前の行で update() を呼び出しても動作する。一方、関数式の方は、宣言した行より手前で delete() を呼んだりすると、その時点では未定義だということでエラーになってしまう。

即時関数を1文字ずつ見直してみる

それでは即時関数に戻る。

(
  function() { }
) ();

インデントを入れたりしてみた。

1行目と3行目の1文字目にあるカッコは何なのかというと、function() {} を囲んでいるカッコだ。よく var hoge = (1 + 2 + 3); などと書くような、処理のひとまとまりをまとめるためのカッコとして使われている。

3行目の最後にある () は何かというと、コレが関数呼び出しの際に使うカッコだ。update()() 部分と同じだ。

つまり、function() { } という無名関数を定義し、カッコで囲んだそれを、その場でメソッドとして実行している、ということになる。

引数が取れる理由も納得

(
  function(w) {
    // 引数 w は window オブジェクトの参照になる
  }
) ( window );

これも、その場で定義した無名関数に、引数として window を渡しているワケで、名前を付けてよく見る形にしてあげれば、以下のつくりと同じだ。

// 関数宣言ココカラ
function hoge(w) {
  // 引数 w を window オブジェクトと見なした処理を記載しておく
}
// 関数宣言ココマデ

// 定義した関数を引数付きで呼び出す
hoge(window);

この hoge という関数名がなくなり、関数宣言ココカラ関数宣言ココマデ をカッコで囲んでひとまとまりにしてあげて、最終行に残った (window) 部分をくっつけてあげれば、先述の引数付き即時関数になる。

JavaScript は面白いですねぇ~。