関数リテラルにつまづく・・・
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って表示されました。きっと関数の引数としてオブジェクトを使ったから、そのオブジェクトのプロトタイプは有効なんでしょうね。オブジェクトで渡せば、関数外で定義したプロパティ値とかもちゃんと参照できるんだね。
ちょっとずつちょっとずつ。しっかりみにつけよう。