イベント発生時に無名関数を実行

2007.04.17 / javascript

HTMLの任意の要素に対して、JavaScriptではonClick, onLoadなどのイベントハンドラに処理を直接結びつけることができます。たとえばこんなかんじ。

  <a href="#" onClick="window.alert('Hello, World!');">こんにちわ!</a>
  

こうすると「こんにちわ!」をクリックすると「Hello, World!」のウィンドウが表示されます。至極簡単。 ただ、HTMLの中にJavaScriptを埋め込む記法はどうなんだ?という意見も当然あるかと思いますが、ここではそれについては割愛。実際、僕も最近はほとんどPrototype.jsのEvent.observe()を使って、イベントに対する処理はまとめて定義しちゃうことが多いです。

さて、話は戻って上記の話をさらにすすめることに。今度は複数の処理を逐次処理させることにします。一番簡単なのは、逐次処理の内容を1つの関数にまとめておいて、その関数をイベント発生時に呼び出す方法。たとえばこんな感じ。

  function hello(){
   document.title="こんにちわ!";
   window.alert("こんにちわ!!");
  }
  

こんなのを定義しておいて

  <a href="#" onClick="hello();">徹底的に挨拶</a>
  

こうやって呼び出すとOK。ただし、グローバルな領域にhelloが汚染するのは少し気持ち悪いです。特にイベント発生時に呼び出される処理が単純なものであればあるほど、グローバルな領域は可能な限りクリーンにしておきたい限り。

と、いうわけでこういうときには無名関数を使うのがオススメ。そうするとかなりスッキリと書くことができます。実際のコードはこんな感じ。

  <a href="#" onClick="(function(){ document.title="こんにちわ!"; window.alert("こんにちわ!!");})()">徹底的に挨拶</a>
  

ポイントは(function(){})()の箇所。ちょっと分かりにくいかもしれませんが、「function(){}」自体を「( )」で囲って、直後に「( )」と書くことで、その場で実行しているところです。この方法を使うことで、グローバルな領域は汚染することなく、簡単な処理から少し複雑な処理までをイベントに結びつけることができます。

最初はonClick=“function(){処理}” という書き方をしていたのですが、これだと中の処理が実行されなくて、うーん。。。と困っていたのですが、要するにこれだとイベント発生時に無名関数を定義しているだけで、実際の処理は行われない、ってことのよう(で、いいのかな?)定義した内容を実際に処理させるためにも、最後の「( )」が効いてくるわけです。

余談ですが、Googleのサービスの何かのJavaScript(Gmailか何か)は、超膨大なコード量にもかかわらず、全コードを(function(){膨大な処理})()という記法をしていたことがありました。今もそのままかどうかは分かりませんが、当時はこの書き方が謎だったのですが、今思えばこれもグローバル領域の汚染を回避する方法だったんですね。これくらいの徹底した姿勢には、うーんさすが。。と思わされるところがあります。