関数スコープメモ
Javascriptのスコープではまったのでメモしておく。
なんでこうなるのかは、いまだに理解してない。
なんででしょうか?教えて偉い人!!
元のHTMLとJSソース
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <title>test page</title> </head> <body> <script type="text/javascript"><!-- // ここにJSを入れる --></script> </body> </html>
オーソドックスな気か方(プログラムとしてはネームが汚染されてきちゃないけどね)
<script type="text/javascript"><!-- function f(){ alert("関数だよ"); }; f(); --></script>
これも「関数だよ」アラートがあがってくる。
<script type="text/javascript"><!-- f(); function f(){ alert("関数だよ"); }; --></script>
書き方を変えても、想定通り「関数だよ」のアラートがあがってくる。
<script type="text/javascript"><!-- var f = function(){ alert("関数だよ"); }; f(); --></script>
これだと、「f is not function」 とエラーになる。
<script type="text/javascript"><!-- f(); var f = function(){ alert("関数だよ"); }; --></script>
なぜに。。。。
ポイントは、関数を変数に格納してることだと思うんだけど。。。
スコープの問題と関数・変数の評価の問題なんかなー。
ちなみに元々は、他人のJSのソース(JSでは有名な人かな?)を読んでいて勉強したテクニックなんだけど...
追記
色々勉強して、なんでこうなるのか?ということがわかった(つもりでいるので、恥をしのんで書いてみる)
JavaScriptでは "f()" みたいに、オブジェクト、変数などの後ろに"()"と書くと
あきらかに間違っているにもかかわらず、なんでも関数として評価され直ぐに実行されるようです。
例えば、以下のJSは明らかに関数ではないのに関数として評価されている
1(); //true is not a function true(); //true is not a function 'mmm'(); //true is not a function
なので、1番目と3番目は関数で評価されたときにはすでに、
f()は宣言されているから特に問題なし。
一方、先行して評価しているにもかかわらず、
2番目と4番目の結果の違いが出ているのには、名前付き関数(と呼ぶの?)と無名関数が絡んできます。
今のところの理解だと、2番目はfunction f()という関数が定義されている。
4番目はコードには無名関数が定義されていて、それがvarに格納されているが、
スクリプトのエンジンがまだ該当する変数(この場合 var f )にまで到達していないため、
評価が解決できないのだという認識です。
これで大丈夫かな??