a
およびb
は、0
および1
から始まるシーケンスの現在の番号と次の番号を表します。 n
はフィボナッチシーケンスのどの要素が返されるかを指定するカウントダウンタイマーです(EG:n = 10
は55
を返します)。
この関数は、それが配列のn番目の数を計算することを意味引数n
を受け入れることによって動作:
function fib(n) {
コード次に、シーケンス内の次の数を計算する関数を定義する:
function(n,a,b) {
return n>0 ? arguments.callee(n-1,b,a+b) : a;
}
基本的に、この無名関数は、実行するたびにn
を1ずつカウントダウンし、同時に、a
とb
をtの次の数字に移動します彼はシーケンス。 n
が0
に等しい場合、シーケンスは完了し、現在の番号a
が返されます。
arguments.calleeは、現在実行中の関数を参照しているため、コードは単に新しい引数でそれ自体をコールバックすることを意味します。言い換えれば、 "ループ"の次の反復を開始することです。
最後に、(n,0,1);
というコードは、実際にfib
に呼び出され、パラメータはn,0,1
です。上記のスニペットから除外したreturn
ステートメントは、無名関数の戻り値をとり、fib
の呼び出し元に返します。このように再帰を使用すると、テールコールの最適化を持たないJavaScriptなどの言語では効率的ではありません。大きいn
の場合は、再帰の代わりに標準のループ構造を使用してこれを書いた方が良いでしょう。
JavaScriptは最終的にES6以来のテールコールの最適化を持っています。http://benignbemine.github.io/2015/07/19/es6-tail-calls/ –
言語がサポートしていますが、多くの実装はまだありません。https ://kangax.github。io/compat-table/es6/ –