これをグローバルスコープで書くと:
(function(){})();
ステートメントの実行時に無名関数が作成され、ステートメントの実行直後に破棄されますか?
これを関数に書くと:
function foo()
{
var a=1;
(function(){})();
a++;
}
匿名関数はfooが戻るまで存在しますか、それともそのステートメントの実行中に存在しますか?
この特定のケースでは、ほとんどのエンジンは何もしないため、その機能を完全に最適化します。
しかし、関数にコードが含まれていて、実際に実行されていると仮定しましょう。この場合、関数は、コンパイルされたコード、バイトコード、またはインタープリターのAST)のいずれかとして常に存在します。
常に存在するわけではない部分は、スコープと作成される可能性のあるクロージャーです。その関数とクロージャ用に作成されたスコープは、関数が実行されるか、特定のバインドされたスコープ/クロージャを持つ関数への参照が存在する場合にのみ存在します。
したがって、組み合わせ関数参照+スコープは、ステートメント_(function(){})();
_の実行時に割り当てられ、そのステートメントの後に解放できます。ただし、コンパイルされたバージョンのfunction(){}
は、後で使用するためにメモリに残っている可能性があります。
コンパイルと最適化がちょうど間に合うエンジンの場合、関数はコンパイルされたさまざまなバージョンに存在することさえあります。
最新のjsエンジンのJIT +オプティマイザー部分は複雑なトピックです。v8の大まかな説明はここにあります html5rocks:JavaScriptコンパイル :
V8では、Fullコンパイラはすべてのコードで実行され、できるだけ早くコードの実行を開始し、優れているが優れていないコードをすばやく生成します。このコンパイラは、コンパイル時に型についてほとんど何も想定していません。変数の型は実行時に変更される可能性があり、変更されることを想定しています。
完全なコンパイラと並行して、V8は最適化コンパイラを使用して「ホット」関数(つまり、何度も実行される関数)を再コンパイルします。 [...]最適化コンパイラでは、操作は投機的にインライン化されます(呼び出された場所に直接配置されます)。これにより、実行が高速化されますが(メモリフットプリントが犠牲になります)、他の最適化も可能になります。
したがって、生成されたコードは元のコードとほとんど類似していない可能性があります。
したがって、即時に呼び出される関数式は、インライン化を使用して完全に最適化される場合もあります。
これをグローバルスコープで書くと:
(function(){})();
ステートメントの実行時に無名関数が作成され、ステートメントの実行直後に破棄されますか?
T.nieseが言ったように、エンジンがその機能を完全に最適化する可能性があります。それで、それにいくつかのコードがあると仮定しましょう:
// At global scope
(function(){ console.log("Hi there"); })();
エンジンは、そのコードがエラーをスローしないことを保証できないため(たとえば、console
を別のものに置き換えた場合)、それをインライン化することはできないと確信しています。
今の答えは:それは異なります。
言語/仕様レベルから、コンパイルユニット(大まかに:スクリプト)内のすべてのコードは、コンパイルユニットが最初にロードされるときに解析されます。次に、その関数は、コードが段階的な実行で到達すると作成され、作成後に実行され(呼び出しの実行コンテキストの作成が含まれます)、実行されるとすぐにガベージコレクションの対象になります(実行コンテキストとともに)何もそれへの参照を持っていないので。しかし、それは単なる理論/高レベルの仕様です。
JavaScriptエンジンの観点から:
興味深い読み物となるV8ブログの記事をいくつか紹介します。
これを関数で書くと:
function foo() { var a=1; (function(){})(); a++; }
匿名関数はfooが戻るまで存在しますか、それともそのステートメントの実行中に存在しますか?
その関数にconsole.log
があり、それが書き込み可能なグローバルに依存しているという事実が正しいと仮定しましょう(は私の側の仮定です) (console
)は、単にインライン化できないことを意味します。
高レベル/仕様の答えは同じです。関数は、スクリプトがロードされるときに解析され、スクリプトに到達して実行されると作成され、実行が完了するとGCの対象になります。しかし、繰り返しになりますが、それは単なる高レベルの概念です。
おそらくエンジンレベルでは状況が異なります。
foo
が戻ったときにGCを簡単にします。)