es 6関数の末尾呼び出し最適化事例分析


この例は、es 6関数の最後呼び出し最適化を説明する。皆さんに参考にしてあげます。具体的には以下の通りです。
最後の最適化は何ですか?
テイルコールは関数式プログラミングの重要な概念で、それ自体は非常に簡単で、一言ではっきり言えます。つまり、ある関数の最後のステップは別の関数を呼び出すことです。

function f(x) {
 return g(x)
}

上のコードでは、関数fの最後のステップは、関数gを呼び出します。
以下の3つの場合は、いずれもテールコールに該当しません。

//    
function f(x) {
 let y = g(x)
 return y
}
//    
function f(x) {
 return g(x) + 1
}
//    
function f(x) {
 g(x)
}

最後のステップで操作すればいいです。

function f(x) {
 if (x > 0) {
  return m(x)
 }
 return n(x);
}

最後の呼び出しが他の呼び出しと異なるのは、その特殊な呼び出し位置にあるからです。
関数コールはメモリに「呼び出しログ」を形成し、また呼び出しフレームと呼ばれ、呼び出し位置や内部変数などの情報を保存することを知っています。関数Aの内部で関数Bが起動されると、Aの呼び出しフレームの上にBの呼び出しフレームが形成される。B運転が完了すると、結果をAに戻し、Bの呼び出しフレームが消えます。関数Bの内部で関数Cが呼び出されると、Cの呼び出しフレームがもう一つあり、これに類推する。すべての呼び出しフレームは、コールスタックを形成する。
テイルコールは関数の最後のステップであるので、外部関数の呼び出しフレームを保留する必要はありません。呼び出し位置、内部変数などの情報は使用されません。外部関数の呼び出しフレームに代えて、直接にイントラ関数の呼び出しフレームを使えばいいです。

function f() {
 let m = 1;
 let n = 2;
 return g(m + n);
}
f();

//    
function f() {
 return g(3);
}
f();

//    
g(3);

上のコードでは、関数gがテイルコールではない場合、関数fは内部変数mとnの値、gの呼び出し位置などの情報を保存する必要があります。しかし、gを呼び出した後、関数fは終了するので、最後のステップまで実行すれば、f(x)の呼び出しフレームは完全に削除され、g(3)の呼び出しフレームだけを保留することができる。
これは、「テイルコール最適化」と呼ばれ、すなわち、イントラ関数の呼び出しフレームのみを保持します。すべての関数が最後の呼び出しであれば、実行するたびに、呼び出しフレームは一つしかないので、メモリを大いに節約することができます。これが「テールコール最適化」という意味です。
なお、外部関数の内部変数を使用しない限り、内部関数の呼び出しフレームは外層関数の呼び出しフレームに取って代わることができ、そうでなければ「テール呼び出し最適化」はできない。

function addOne(a){
 var one = 1;
 function inner(b){
  return b + one;
 }
 return inner(a);
}

興味のある友達はオンラインHTML/CSS/JavaScriptコードを使ってツールを実行できます。http://tools.jb51.net/code/HtmlJsRun上記コードの運行効果をテストします。
もっと多くのJavaScriptに関する内容は当駅のテーマを調べられます。「JavaScript常用関数技術のまとめ」、「javascript対象向け入門教程」、「JavaScriptエラーとデバッグテクニックのまとめ」、「JavaScriptデータ構造とアルゴリズム技術のまとめ」及び「JavaScript数学演算の使い方のまとめ
本論文で述べたように、JavaScriptプログラムの設計に役に立ちます。