2011-08-08 7 views
3

下のスクリプトは正しい形式のJavaScriptですか?これは正しい形式のJavaScriptですか?

function foo(){ 
    return function(x){ 
     alert(x) 
    } 
} 
foo()("bar"); 
    ↑ ↑ 
    There are 2 parenthesis. 

worksしかし、正しい形式であるかどうかわかりません。
「はい」の場合は、これも正しいことを意味していますか?

function foo(){ 
    return function(){ 
     return function(){ 
      return function(){ 
       return function(x){ 
        alert(x) 
       } 
      } 
     } 
    } 
} 
foo()()()()("?!?!?!"); 

それは私には奇妙に見えるが、それは...

+2

期待どおりに動作する場合は、その後、私はそれは醜い – Phil

答えて

1

関数の次数呼び出しがパラメータを追加することによって示されている: -

function foo(a){ 
    var A=a; 
    return function(a){ 
     A+=a; 
     return function(a){ 
      A+=a; 
      return function(a){ 
       A+=a; 
       return function(a){ 
        A+=a; 
        alert(A) 
       } 
      } 
     } 
    } 
}; 
foo('a')('b')('c')('d')('e');// displays abcde 

あなたは、関数の戻り値を作ることができますそれは、繰り返し呼び出すことができるので、それ自体は、例えば

var foo = (function(){ 
    var v=1; 
    return function f(x){ 
     return x==undefined?v: (v*=x, f); 
    } 
})(); 
foo.toString=function(){ 
return foo(); 
}; 
alert(foo(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)); 

ネストは、プライベート変数を維持するために、通常は例えば

var factorial=(function(n){ 
    var precog = [1,1]; 
    var factorial= function f(y){ 
     if(precog[y]==undefined){ 
      precog[y]=y*f(y-1); 
     } 
     return precog[y]; 
    }; 
    factorial(n);// initialise some precogs 
    return factorial; 
})(100); 

precogは角括弧で宣言されているため、階乗関数によって内部的に計算された値は混乱することはありません。

変数に割り当てられた機能は通常通りと呼ばれている: -

factorial(3); 
+0

ps上記の関数名fはオプションです。つまり、関数が評価される前に代入が行われるため、var階乗を呼び出すことができます。 – QuentinUK

2

はい、これは有効な構文作品ですありません。文法的に間違っていることは何もありません。新しいコーダーが少し混乱するかもしれません。繰り返される()は、前の式が関数として呼び出されていることを示します。このように書かれている場合、あなたの最初の例は、もう少し明確にすることがあります。

(foo())("bar"); 

あなたの最後の例では、効果的である:

((((foo())())())())("?!?!?!"); 
+2

があること、それは有効な構文です同意するが、同意見た目より他のすべての問題を見ることができません何も "書道的に間違っている"。読むのが難しく、理解しにくいので、スタイルが悪いので、保守やバグの修正は実用的でないほど難しいでしょう。 – RobG

+1

@RobG: '(function(){...})();'のような同様の構文は、インクルードされたスクリプトでプライベートスコープを作成するために常に使用されます。文法的に間違っているだけでなく、状況によっては奨励されます。 – cdhowie

+1

直ちに呼び出される関数epxressionの使用は、呼び出しの連鎖とは少し異なります。 IIFEの場合でも、外側のブラケットは必要ではありませんが、最初からあなたが読んでいるものを知ることができるので、「良いスタイル」として含まれています。 (関数(){...}()) 'は関数' '{...}()'よりもはっきりしています。 – RobG

2

これは、これらの構成要素を呼び出すための正しい方法でしょう。より良い質問は、なぜ...あなたが投稿したことをすることができますが、私は5回ネスト機能を正当化することは非常に難しいと感じています。

+1

おそらくこれはほんの単純化された例であるか、またはユーザーが学習しようとしていると思われます。私は2つのレベル( 'foo()()()')の関数を返す関数が実際に有用である現実世界のケースを持っていました。 – cdhowie

1

Javascriptの関数は「一次」オブジェクトであり、他のオブジェクトと同様に作成して渡すことができます。そうです、あなたは別の関数からそれらを返し、あなたが言及して正確に何を行うことができます。

var f = g(); 
f(); 

// The same as 
g()(); 
+0

それは私にエラーを与える... –

+0

@Derek - * g * firstを定義する必要があります。 '関数g(){関数(){}}を返します。 – RobG

関連する問題