- ベストアンサー
無名関数を実行する方法と注意点
- 無名関数を実行する場合にはセミコロンの有無に注意が必要です。
- セミコロン付きで実行する場合とセミコロンなしで実行する場合がありますが、どちらでもイベントは実行されます。
- また、関数名の後にカッコをつけることで関数を実行できる場合もありますが、この場合は注意が必要です。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
JavaScript の文法を一通り眺めましたか? 関数にカッコ () を付けると「その場で関数を実行し、戻り値で置き換える」の意味になります。 この場合、 window.onload = init(); は init がその場で実行されて戻り値(なし=undefined)に変換され window.onload = undefined; となります。よほど運が良いのでない限り、これがうまくいくはずありません。 一方、 window.onload = init; と「実行しないで」セットした場合、load 発生時にブラウザが自動的に init を実行します。あるいは、適当な時点で window.onload() と手動で実行することもできます。 試行錯誤も結構ですが、一通り文法を眺めてからの方が効率が良いと思います。 -- なお、JavaScript の関数は無名だけでなく名前付きのものもあります。関数オブジェクトは名前付き関数の宣言、名前付き関数の式、無名関数の式に分類され、それぞれ特徴があります。まあ、いちいち「無名」関数を強調するのが変なのは同意です。 また、script 要素を head 要素内に書く必要もありません。むしろ、script 要素はブラウザの逐次描画を妨げますので、(@defer を付けないなら)読み込みの遅い外部スクリプトは文書末尾にまとめるべきですし、特定の要素の直前、直後に置いた方が良い場合もあります。 セミコロンに関しては、JavaScript では全ての文の末尾に必要です。ただ、特定の場合に省略できるというだけです。もし将来的にスクリプトの圧縮などを考えているのなら、付ける癖を着けた方が無難です。
その他の回答 (3)
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
No. 2 の補足に対しての回答ですが、 init() と書いた場合は、Scriptタグが読み込まれた時点で init() も 実行されてしまいます。つまり html を読み込んだ順序に従って、 スクリプトの実行とHTMLの解釈が順序よく進むという形になります。 HTML全体のソースがないのでなんともいえませんが、常識的に <head></head> の中に script を記述しているなら、init() 実行時に まだフォームは存在していないので、エラーが起きるはずです。 #scriptは headの中に書くのが正しいですが、ほとんどのブラウザは #任意の場所に置くことを許しています。 init と書いた場合は window の onload イベントで init()が動作するので、 すべての HTML の解釈が終了し、ブラウザがイベントハンドラーモードに 切り替わったあとで実行されます。意図したとおりに実行されるでしょう。
お礼
返事が遅れてしまい、申し訳ありません。 再度のアドバイスを頂き、感謝します。 なるほど、やはり()を付けるのはエラーの原因になりそうですね。 噛み砕いたアドバイス本当にありがとうございました。
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
質問がどこに書かれたJavascriptのどのようなコードの話なのか書いてないのが きになりますが、 Javascript は、文を解釈する際、文法エラーを起こす文で、 改行を ; に置き換えて文を分割するとエラーがなくなる場合、 改行を ; に置き換える というちょっと気持ちわるい 機能があります。 ブラウザによって微妙に動きが違うこともあり、使用は推奨されていません。 JSLINTなどのツールを使って問題箇所を発見し、セミコロンを追加することを おすすめします。 それと、質問では「無名関数」と指定されていることがちょっと気になります。 JavaScript では関数は「実行コードを持つオブジェクト(ハッシュ)」であり、 関数名は関数オブジェクトが代入された変数やプロパティの名前なので、 関数自体は全て「無名」です。 ですから ■window.onload = init(); 変数 init に格納された関数オブジェクトを「実行」し、その実行結果を、window オブジェクトの onload プロパティにセットする。 window.onload = init; 変数 init に格納された関数オブジェクトをwindow オブジェクトの onload プロパティにセットする(関数はオブジェクトなので参照のみがコピーされます)。 ということになります。全く意味がことなります。
お礼
アドバイスを頂き、感謝します。 > 質問がどこに書かれたJavascriptのどのようなコードの話なのか書いてないのが > きになりますが 申し訳ありません。 長いソースコードを見るのが苦痛だと思い省いてしまいました。 また、回答者様のおっしゃるとおり、; (セミコロン)は付けるように心がけます。 > JavaScript では関数は「実行コードを持つオブジェクト(ハッシュ)」であり、 > 関数名は関数オブジェクトが代入された変数やプロパティの名前なので、 > 関数自体は全て「無名」です この事は初めて知りました。 どうもありがとうございます。 ただ、少しinitの () を付けると付けないとの違いが理解できないのでそれを補足に書かせて頂きます。
補足
window.onloadというイベントハンドラを調べてみると、HTMLドキュメントが読み込まれたときに実行すると書かれています。 まずソースコードを書き足さなかったので、以下にscriptエレメントの部分だけ書かせて頂きます。 <script type="text/javascript"> var hourBox, minBox, secBox; var timer; window.onload = init; function init() { hourBox = document.clockForm.hour; minBox = document.clockForm.minute; secBox = document.clockForm.sec; dClock(); } function dClock() { var now = new Date(); var hour = now.getHours(); var min = now.getMinutes(); var sec = now.getSeconds(); if (hour<10) hour = "0" + hour; if (min<10) min = "0" + min; if (sec<10) sec = "0" + sec; hourBox.value = hour; minBox.value = min; secBox.value = sec; timer = setTimeout("dClock();", 1000); } </script> ここからは大変お手数をおかけするのでアドバイスしてもらいたいのですが、面倒なら仕方ありません。 このscriptエレメント内でのinitの()があるのと無いのでは動きがどう違うのでしょうか。
- osamuy
- ベストアンサー率42% (1231/2878)
> ; (セミコロン)は普通付けるのがいいのでしょうか。 どっちでも良いです。付けるもの付けないのもどちらもメリット・デメリットがあります。 大事なのは、どっちかに統一することです。 付けるなら、必ず付ける。付けないなら、絶対付けない。 コードに揺らぎがあると、バグの温床になるので。 >何故、initに()を付けてはいけないのかが分かりません。 ()をつけると、window.onloadに代入するときに、init()が実行されます。 ウインドウのロード完了時に自動的に呼び出したいってのが、本来の意図だとすると、それはかなわないでしょう。 意図どおりではないかもしれないけど、実用上は問題になってないだけではないかと。
お礼
アドバイスを頂き、感謝します。 ; (セミコロン)は付けるようにします。
お礼
返事が遅れてしまい申し訳ありません。 アドバイスを頂き、感謝します。 まず忠告ありがとうございます。 もう一通りテキストは終わったのですが、仮にinit関数とした場合何故()を付けないのかはずっと疑問でした。 テキストにはさも当然のように書かれていたのでずっと理解できないまま終わって今いました。 回答者様のアドバイスでどうにか理解できた次第です。 ソースコードを書く際にファイルが初めからhead部分とbody部分に分かれて書かれていたのでそのまま鵜呑みにして書いてました。 これからは気をつけます。 それと、セミコロンは付けるようにします。 分かりやすいアドバイス本当にありがとうございました。