今回の件に関しては、
No.8の「関数宣言」と「関数式」という考え方が一番すっきり理解できると思います。
> var v = (function (f) f) (function (g) g) (function (n) n) (1);
これは、
> var v = (function (f) f) (function (g) g) (function (n) n) (1);
1. function (f) f が、引数 function (g) g をリターン
> var v = (function (g) g) (function (n) n) (1);
2. 1でリターンされた function (g) g が、引数 function (n) n をリターン
> var v = (function (n) n) (1);
3. 2でリターンされた function (n) n が、引数 1 をリターン
> var v = 1;
という順序で処理されていると思います。
fやgが関数オブジェクトなので算術演算の対象には出来ないのでしょう。
無理矢理alertでも入れてみれば、fやgが何かは分かると思います。
var v = (function (f) (alert("f="+f),f)) (function (g) (alert("g="+g),g)) (function (n) (alert("n="+n),n)) (1);
また、かっこで優先順位を変えれば期待している結果になると思います。
var v = (function (f) f*2) ((function (g) g/3) ((function (n) n) (1)));
> 過去、別の質問でWernerさんに回答していただいたのを覚えています。
そのときの人だと気づいてませんでした^^;
そのときに、functionオブジェクトがプロパティ持てる話はしてましたね。
お礼
> 1つめから3つめへ変形する過程を述べるため、強調したかったのでしょう。 確かにそうですね。 私も2つめのコードがあったおかげで、匿名関数についてのヒントを得ることが出来ました。 > ({x:1}).toString()は正常 > このことも考えると、ブラウザにとって{}の記号は扱いづらいのでしょう。 なるほど、なるほど。 そう考えると、わかるような気がします。 「"{}" の構文解析が難しいから、"()" でグループ化する」というニュアンスで理解しました。 > evalは関数で、引数が文字列ならそれを解釈して実行、というのが本来の?目的ですからねぇ・・・ やはり、eval() は代替手段ですね。同一と捉えるのは無理があるようですね。 > hoge("fuge"); はhogeという関数を実行。 > (hoge)("fuge"); はhogeという変数に代入されている、functionへの参照を取得し、実行。 「functionオブジェクトの参照を取得する」という考え方でいいのですね。 > 「参照渡し」はご存知でしょうか? JavaScriptでは「参照渡し」を意識したことがありませんが、PHPのユーザ定義関数で引数の参照渡しは覚えましたので理解できていると思います。 オブジェクトの実体ではなく、参照 (エイリアス、ショートカットのようなもの) を渡すというイメージを持っています。 > (a?hoge:piyo)("引数") > といった表記ですと、?:の二項演算を“実行した結果”の参照を返し、その関数を展開、となります。 こんな書き方もあるんですね。JavaScriptは奥が深いです。 # ところで、これは「二項演算」というのでしょうか?(私はこれを「三項演算」と認識していました。) # 調べてみると、二項か三項かは被演算子の数で決まるとあるので、"hoge" と "piyo" で2つカウントしている…のでしょうか。 実際のコードをあげながらの説明がとても理解しやすく、参考になりました。 ありがとうございます。