2017-11-03 34 views
3

私はなぜ興味:関数を呼び出す複数回

(function() { return 'one' })()() 

リターン:

TypeError: (intermediate value)(...) is not a function 

ない:

TypeError: 'one' is not a function 
+0

興味深い質問:)あなたの関数を割り当てるならば、 'Uncaught TypeError:f(...)は関数ではありません。 ' '中間値'は関数が匿名であるという事実から来ているようだが、エラーメッセージは最初の呼び出しが実際にはまだ評価されていないのと同じである。 – sjahan

+0

この関数は文字列を返します。実行後、2番目の関数呼び出しは 'one()'と同じではなく、 'one()'と同じではありません。 – axiac

答えて

2

エラーメッセージが変数名や他のIDを使用言いたいことは、機能ではないということです。戻り値は何にも割り当てられていないので、エンジンがintermediate value

+0

「one」は文字列だけですが、eatherに割り当てられていないか、間違っていますか? – Src

+0

@Srcはい、それは単なる文字列であり、変数ではありません。 – TKoL

+0

エンジンの名前に代わってエンジンが吐き出すものに割り当てられていないからです。 –

0

を言うので、それは、識別子を持っていない中括弧()で、それは(function() { return 'one' })は、中間結果を得表現になったときのでおよびそれらの結果はまだ変数にバインドされていません。spec 1として

Specification type values are specification artefacts that do not necessarily correspond to any specific entity within an ECMAScript implementation.

Specification type values may be used to describe intermediate results of ECMAScript expression evaluation but such values cannot be stored as properties of objects or values of ECMAScript language variables.

+1

なぜこれがダウン投票になったのか分かりません。それは私よりも良い答えです。 –

2

documentation of the error message "TypeError: "x" is not a function"は説明:

What went wrong?

It attempted to call a value from a function, but the value is not actually a function. Some code expects you to provide a function, but that didn't happen.

をまた、このエラー及びそれらによって報告された実際のエラーメッセージをトリガするいくつかのコードの例を提供します。ここではコピーしませんが、それらを詳しく見て、それらが生成するエラーメッセージに注意してください。

「X」部分は関数であることが期待されているオブジェクトの名前によって実際のエラーメッセージで置換され、それはありません。

この場合のオブジェクトには名前がありません(表現の評価中に計算された中間結果です、以下の説明を参照してください)、エンジンはその名前を報告することはできず、可能な限り役立ちます。おそらくこの方法より説明的なので、"(中間値)(...)"と報告します。格納されていないが別の値の計算に使用されている関数によって返された値です。

中間値は何でもかまいませんので、代わりに実際の値を報告することはできません。複雑なデータ構造の場合は、多くの情報を追加せずにエラーメッセージが肥大化します。

明らかに私は最初から質問を理解していませんでしたが、なぜエラーが生成されたのかを説明する私の最初の答えは、なぜエラーメッセージではなく、OPが期待するものではありません。


このコード...

(function() { return 'one' })()() 
  1. は...それを呼び出す...

    function() { return 'one' } 
    
  2. ...無名関数を作成します...

    (function() { return 'one' })() 
    
  3. ...その後、別の関数として、関数が返す値を解釈し、それを呼び出そう:

    (function() { return 'one' })()() 
    

ステップ#1で作成した関数は、文字列を返します('one' )が呼び出されたとき(ステップ#2)。

ステップ#3では、コードの効果は'one'()を呼び出すのと同じです。これはone()と同じではありません(ご想像の通りです)。

エラーメッセージで参照される中間値は、変数に保存されずに(関数として)式で使用される最初の関数呼び出しによって返された文字列です(「中間」語句の説明です)。 )

エラーメッセージに明らかなように、'one'は関数ではなく、(式の中に2番目の括弧を置くことによって)関数として使用しようとしても機能しません。

それを動作させるためには、ステップ#1で作成した匿名関数は次のように、別の(匿名)関数を返す必要があります。今、それが呼び出されたときに

(function() { return function() { return 'one'; } })()() 

、外側の関数は、匿名を返します。元のコードでステップ#1で作成された無名関数と同様の関数です。この関数が呼び出されると(())、文字列'one'が返されます。

これはおそらくあなたが望むものではありません。文字列として名前を指定した関数を呼び出すことは、(いくつかの強力な理由により)避けるのが最善の言語機能であるeval()を使用することによってのみ可能です。

+0

確かに、私はまた、ステップ3で、コードの効果は 'one'()を呼び出すのと同じだと考えましたが、それは真実ではないことが分かります。それは私の質問についてです! – Src

+0

私はあなたの質問を初めて理解していないと思います。私は答えを更新しました。 – axiac

関連する問題