onloadと関数の呼び出しについて

イベントハンドラであるonloadについて、どうもすっきり納得できないことがあって、しばらく考えていたが、 なんとなく分かってきたので、そのことを記しておく。

onloadが使われる場合として、HTMLの各要素に属性として記述する場合がある。 そこで関数を呼び出す場合はonload="kansu()"のような形で()を付けた形で記述する。 具体的には下記のような形である。


<script type="text/javascript">
founction kansu(){
/*処理を記述*/
}
</script>
<body onload="kansu()">

しかしながら、windowオブジェクトに対してonoloadで関数を呼び出す場合は、下記のようになる。


<script type="text/javascript">
founction kansu(){
/*処理を記述*/
}
window.onload=kansu;
</script>

なぜ同じonloadで呼び出しているのに、()が付いたり、付かなかったりするのだろうか?

実はこれにはちゃんとしたわけがある。 関数についている名前(この場合はkansu)は、関数を呼び出すときにも使えるが、関数をオブジェクトとして扱うときにも使えるのだ。 例えば関数を呼び出すときの書式は


kansu();

である。 一方、関数をオブジェクトとして扱う場合は当然


hensu=kansu;//関数オブジェクトを変数hensuに代入

という風に関数名のみで()は付かない。

また、HTMLの各要素のイベントハンドラ属性には、""の中に関数以外のコードも直接書くことができる。 要するに


<body onload="alert('おいっす!')">

と書くと、""の中に書かれたステートメントをJavaScriptのコードとして実行するのだ。

""の中で関数を呼び出すときも、当然同様に関数を呼び出すコードを記述するので、


<body onload="kausu()">

となるのである。

一方windowが読み込まれたら関数を実行するという場合、 windowオブジェクトのonload イベントハンドラに対して関数オブジェクトを代入する形のステートメントを記述する。 すなわち、


window.onload=kansu;

となるのだ。 上記のhensuwindow.onloadに変わっただけだと考えればいい。 言ってみれば、windowオブジェクトのonloadというプロパティのようなものに関数オブジェクトを代入する感じである。 つまり単なる関数の呼出しとは別のステートメントを記述しているのだから、書き方が違うのは当たり前なのである。