関数リテラルにつまづく・・・

javascriptの関数リテラルの動きがしっくりつかめない・・・

参考書通りにコードを書いていたが、関数リテラルっていったいなんなの!?って思いました。たとえば、下のコード

function flexisum(a) {
        var func = function() { return "localspace" ; };
        var total = 0 ;
        for(var i=0; i<arguments.length; i++) {
                var element = arguments[i] ;
                if(!element) continue ;

                var n ;
                switch(typeof element) {
/**
 * ここら辺で色々な型判定
 */
                case "function" :
                        n = element() ;
                        break ;
                }
    alert(n) ;
        if(typeof n == "number" && !isNaN(n))  total += n ;
        else throw new Error("sum()" );
        }
        return total ;
}
var func = function() { return "globalspace" ;} ;
alert(flexisum(func)) ;

まぁ、上のコードは参考書のもろパクリなんですけどね、ちょっと疑問に思ったのが、上のコードだと、下の方のfuncっていう関数リテラルがglobalspaceっていう文字列を返す。
けど、flexisum()関数内で、funcっていう関数が再定義されているから

alert(n) ;

は,

localspace

って表示するかと思いきや、globalspaceって表示されてしまった。

という事は、関数の中で、いくら同じ名前で再定義されていようと、下の

var func = function() { return "globalscope" ; }
alert(flexisum(func)) ;

flexisum関数に関数リテラルを渡している時点で、呼び出された側の関数内では、この関数リテラルの名前とかは関係ないのだな。。。
イメージ的にはアドレスだけ渡している感じなんだろうな。。。

というか!!普通に考えて、関数外で定義した変数は呼び出された側の関数内で、いくら同じ変数名を定義したからといって、その引数に変化はないや。。。。って書いてて気づいた。。。

function hensuTest(str) {
        var hoge = "henkanhoge" ;
        return str ;
}
var hoge = "hogehoge" ;
alert( hensuTest( hoge ) ) ;

うん。上の結果はもちろん hogehoge って表示されるし・・・

ちょっと他の言語にはない関数リテラルに戸惑ってしまった(いいわけ・・・)ちなみに下の様な物は可能

function flexisum(a) {
        var func = function() { return "localscope" ; };
        var total = 0 ;
        for(var i=0; i<arguments.length; i++) {
                var element = arguments[i] ;
                if(!element) continue ;
                var n ;
                switch(typeof element) {
                case "object" :
                        /** ここで、外部で設定した
                         *  プロトタイプを呼び出す 
                         **/
                        element.testalert()  ;
                        break ;        
                }
        if(typeof n == "number" && !isNaN(n))  total += n ;
        else throw new Error("sum()" );
        }
        return total ;
}
var func = function() { return "globalscope" ;} ;
func.prototype.testalert = function() {
                alert("testalert") ;
};
var test = new func() ;
alert(flexisum(test)) ;

上のコードでは、外部で指定したプロトタイプは有効で、testalertって表示されました。きっと関数の引数としてオブジェクトを使ったから、そのオブジェクトのプロトタイプは有効なんでしょうね。オブジェクトで渡せば、関数外で定義したプロパティ値とかもちゃんと参照できるんだね。


ちょっとずつちょっとずつ。しっかりみにつけよう。