概要
ここに関数があります。
function func() {
console.log('hoge');
};
通常は
func();
関数名()
のような形で関数を実行するのに、
window.onload
などイベントハンドラを利用して関数を実行する場合は、
window.onload = func;
関数名
のみで書くのはなぜなんでしょう。
イベント処理の指定方法
JavaScriptのイベント指定には3種類の方法があります。
(1) addEventListener()によるイベントリスナの指定
(2) オブジェクトに指定するイベントハンドラ
(3) HTMLタグ属性に指定するイベントハンドラ
(1) addEventListener()によるイベントリスナの指定
window.addEventListener('load', func);
第1引数にイベントタイプ、第2引数に実行される関数(コールバック関数)を指定しています。
上記例ではload
イベントが検知されると同時にコールバック関数が実行されるので、func
に()
はつけません。
もし第2引数をfunc()
のように括弧をつけて書いてしまうと、JavaScriptが読み込まれた時点でfunc関数
が実行されてしまいます。
(loadよりも早いタイミングで関数が実行される。)
// これはNG
window.addEventListener('load', func());
// これはOK
window.addEventListener('load', function() {
func();
});
(2) オブジェクトに指定するイベントハンドラ
window.onload = func;
これはwindow
オブジェクトのonload
プロパティにfunc
という関数を代入しますよ、という意味です。
window.onload
メソッドはすべてのDOMツリー構造及び関連リソースが読み込まれたあとに自動で発生するので、func
関数に関数実行を意味する**()
をつけないのが正しい**です。
もしwindow.onload = func()
のように書いてしまうと、JavaScriptが読み込まれた時点でfunc
関数が実行され、その戻り値がwindow.onload
メソッドに代入されるだけとなってしまいます。
// これはNG
window.onload = func();
(3) HTMLタグ属性に指定するイベントハンドラ
<input type="button" id="button" onclick="func()">
html要素の属性を用いてonclick="func()"
とイベントハンドラを指定することができます。
ただ(1)、(2)の説明だとfunc()
と関数に括弧がついているので、htmlが読み込まれた時点で関数が実行されてしまうのでは?と疑問に思っていました。
調べたところブラウザが属性を読みとると、その内容から本体を含むハンドラ関数が作成されるようです。
つまりこの記述は以下と同じ意味になります。
button.onclick = function() {
func(); // ここにハンドラ属性に指定した値がはいる
};
ハンドラ関数の中身に属性値がそのまま入るので、括弧がなければ関数が実行されません。
よってhtml属性に指定する場合は関数名()
とする必要があります。
<!-- こう書いてしまうと、 -->
<input type="button" id="button" onclick="func">
button.onclick = function() {
func; // func関数が実行されない
};
どのイベント指定を使えば良い?
(3)のようにHTMLとJavaScriptを混在させる書き方は好ましくありません。
(1)addEventListener()と(2)オブジェクトに指定だと、どちらかといえば**(1)addEventListener()**推奨のようです。
理由
・必要に応じてremoveEventListener()
でイベントハンドラコードを削除できる
・要素に同種のリスナーを複数追加できる
// 同種のリスナーを複数追加できるので、
// console.log('hoge')、console.log('fuga')の両方実行される。
window.addEventListener('load', function() {
console.log('hoge');
});
window.addEventListener('load', function() {
console.log('fuga');
});
// 上書きされて最後に書いたイベントのみ実行されるので、
// console.log('fuga')のみ実行される。
window.onload = function(){
console.log("hoge");
};
window.onload = function(){
console.log("fuga");
};
最後に
window.onload = func;
に括弧がいらない理由を知らなくてもJavaScriptは書ける。
けど、知ってたらもっと楽しいJavaScript。