<<前回「CoffeeScriptって何?」へ<<

 CoffeScriptを3時間で理解するための10のポイントのうち、ポイント1から3までを解説します。ポイント1は「CoffeeScriptはコンパイルで即時関数に変換される」こと、ポイント2は「変数は自動的に宣言される」こと、ポイント3は「リテラルで豊かな表現を可能に」したことです。

POINT1 CoffeeScriptはコンパイルで即時関数に変換される

★「即時関数」でグローバル変数を作らない
★JavaScriptのstrictモードにも対応

 CoffeeScriptで記述されたコードをコンパイルすると、JavaScriptのコードは、(function() {...}).call(this);でラップされた状態で出力されます(リスト7*1。奇異にも見える書き方ですが、実は、JavaScriptの世界では定石とも言える書き方の一つです。匿名関数を定義しておいて、その場で即座に実行することから「即時関数」と呼ぶこともあります。

リスト7●CoffeeScriptから自動生成されるJavaScriptコードの外枠
リスト7●CoffeeScriptから自動生成されるJavaScriptコードの外枠

 でも、よくわかりませんね。その場ですぐに実行するならば、なぜわざわざ関数として定義するのでしょうか。関数を「再利用したい処理をまとめたもの」と理解している人にとっては、なんとも違和感があるのではないでしょうか。

即時関数で変数を封じ込める

 即時関数の目的はすべての変数をローカル変数に封じ込めることです。JavaScriptでは、関数の外側の変数はすべてグローバル変数と見なされます。しかし、グローバル変数が多くなってくると、変数の名前が衝突する可能性が高まり、潜在的なバグの原因になります。「グローバル変数はできるだけ少なく」というのはJavaScriptに限らず、コーディングの鉄則です。

 グローバル変数を減らすにはどうしたら良いでしょうか。その答が即時関数なのです。コード全体を関数でラッピングすることで、すべての変数をローカル化しているわけです。即時関数とは、変数をローカルスコープに押し込めるための便宜的な関数であると言えます。

新しいstrictモードにも対応

 即時関数を呼び出しているcall(this)の部分にも注目です。callはFunction(関数)オブジェクトが提供するメソッドで、「関数の第1引数に与えられたオブジェクトをthisとして、関数を呼び出し」ます。言い換えれば、即時関数の中ではcallメソッドの第1引数のオブジェクトをthisキーワードで呼び出せます。この例では、callメソッドにはthis(グローバルオブジェクト)が渡されています。従って、Webブラウザー環境であればwindowオブジェクトが即時関数の中のthisに引き継がれます。

 もっとも、標準的なJavaScriptの挙動では関数の中のthisはグローバルオブジェクトになりますので、thisの引き渡しを意識する必要はありません。よって、即時関数というと、「(function() {...})();」のような構文で紹介されていることも多いはずです。しかし、この書き方には一つ問題があります。

 JavaScriptのstrictモード*2を有効にした場合、関数内のthisは、グローバルオブジェクトではなく、undefinedになってしまうのです。環境によってthisの内容が変わってしまうのは不都合なので、CoffeeScriptのコンパイラは常に明示的にthisの引き渡しをしているわけです。

この先は会員の登録が必要です。有料会員(月額プラン)は登録月無料!

日経 xTECHには有料記事(有料会員向けまたは定期購読者向け)、無料記事(登録会員向け)、フリー記事(誰でも閲覧可能)があります。有料記事でも、登録会員向け配信期間は登録会員への登録が必要な場合があります。有料会員と登録会員に関するFAQはこちら