関数スコープメモ

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 )にまで到達していないため、
評価が解決できないのだという認識です。

これで大丈夫かな??