2016/09/02 15:21:49

[javascript]即時関数の基本的な記述方法

目次(クリックするとジャンプします)
  • 1:即時関数
  • 2:文と式の話
  • 3:式になる関数 文になる関数
  • 3.1:文になる関数
  • 3.2:式になる関数
  • 3.3:無名関数を裸で記述すると…
  • 4:即時関数への発展
  • 4.1:即時関数は式
  • 4.2:式となるなら()でなくともよいが…
  • 5:引数の取り方
  • 6:まとめ

即時関数

即時関数とは即時に実行される関数です。名前が無いので無名関数の仲間とも言えます。 javascriptではスコープを実現するために必要不可欠な関数で重要度が高いです。今回は即時関数の記述に関してまとめてみましました。

文と式の話

即時関数の話の前に、前提を説明しておきたいです。

プログラミングの記述には大きく分けて二つの要素があります。

式(expression)文(statement)です。

これらの厳密な説明はwikipediaに任せるとして、javascriptでは簡単に言うと、;で閉じないといけないのが式で、閉じなくてもいいのが文という見分けでも構わないです。

式になる関数 文になる関数

文になる関数

名前を付けて関数を定義する場合は文になります。;を付けなくてもエラーにはなりません。

function funcA(){
    //なんらかの処理
}
//;が無くてもいい

式になる関数

無名関数の場合、この記述は式となります。( = が代入演算子で評価しているから式になる)

var funcB = function(){
    //なんらかの処理
};
//;が無いとエラーになる

無名関数を裸で記述すると…

それでは無名関数を代入せずに裸で記述してたらどうなるか?

function(){
    //なんらかの処理
}
//;を付けようがが付けまいがエラーになる

この記述だと式なのか文なのかが定まらない為、エラーになってしまうのです。

即時関数への発展

即時関数は式

エラーになってしまう裸の無名関数を強引に式にしたものが即時関数となります。

(function(){
    //なんらかの処理
});

()で囲まれただけですが、()は「式のグループ化」という役目を担っています。たとえば( (a + b ) * 3 )のような場合も()によってグループ化された式と言えます。

()で囲まれたものはそれ全体が式であるという解釈になるのです。

式となるなら()でなくともよいが…

実は即時関数を作るには、()でなくてもいいです。下記のような書き方でも演算子によって全体が式と認識されるので、エラーにはなりません。

+function(){
    //なんらかの処理
};

-function(){
    //なんらかの処理
};

!function(){
    //なんらかの処理
};

しかしこれらの記述だと、演算子が悪さをして予想もつかない事態を招いてしまうかもしれないです。だから外側に何も影響を及ぼさない()を使うのが一番安全という訳なのです。

とりあえずは無名関数を()で包むと即時関数になると覚えてもらえばOKです。

引数の取り方

即時関数でも引数を取ることができます。 以下のように記述します。

( function( a , b ){
    return a + "は" + b + "です";
} )( "にわとり" , "鳥" );

これは少し不思議な記述に見えるかもしれないです。@MINOもjavascriptを勉強し始めたときは、少し不思議に思った。なぜ後ろの()で指定している引数がちゃんと使われるのだろうと。

普通の関数で引数を取る場合を見て整理してみよう。

//関数を定義 
var funcA = function( a , b ){ return a + "は" + b + "です"; }; 
funcA( "にわとり" , "鳥" ); 
//にわとりは鳥です 
//と表示されるはず

引数a,bを取る関数funcAを定義して実行しています。funcAの中身はfunction( a , b ){ return a + “は” + b + “です”;}(への参照)なので、funcA( “にわとり” , “鳥” );は

function( a , b ){ return a + "は" + b + "です"; }("にわとり" , "鳥" );

と同じ意味になります。これだとエラーになるので、function部分を式にしたのが以下です。

( function( a , b ){ return a + "は" + b + "です"; })("にわとり" , "鳥" );

まんま即時関数です。だから、”にわとり”は第一引数(a)に”鳥”は第二引数(b)にしっかりと引き継がれるのです。

まとめ

今回は即時関数の記述方法を説明してみましました。この即時関数というのはjavascriptが変態である理由の一つだと思うのですが、クロージャを実現する要素としては重要な事この上なしです。

ブロックスコープが無いjavascriptにとってスコープを局所的に作る唯一の方法とも言える(関数が)。

ちなみに英語では即時関数を「immediate function」というそうです。 いやむしろ「immediate function」を訳して即時関数になったというべきか。