つまり、eval
関数の内部を呼び出すことと配列にアクセスできることのarguments
両方で、関数の呼び出し中に追加の設定が使用されます。どちらarguments
もeval
実行されないことがわかっている場合は、この追加の設定をスキップできます。
コンパイラは、arguments
配列が実際にアクセスされるかどうか、またはeval
実際に呼び出されるかどうかを予測しようとはせず、それらが関数に存在するかどうかをチェックするだけです。
arguments
arguments
オブジェクトを使用しない「通常の」関数よりも、オブジェクトを使用する可変個引数関数を呼び出す方が、実行時にコストがかかりarguments
ます。
arguments
オブジェクトが宣言されたときに実行環境をバインドするために必要な追加の手順は、ECMA-262標準の§10.6で指定されています。arguments
オブジェクトの作成は、ややコストのかかる15ステップのプロセスです。基本的にarguments
、渡された引数を入力する必要があり、プロパティ.caller
と.callee
プロパティを作成する必要があります。
標準では、 。arguments
という名前の関数内に宣言されたパラメーター、変数、または関数が既に存在しない限り、関数が実行コンテキストに入るときにオブジェクトを作成する必要があるとされていますarguments
。
最適化の目的で、関数が実際にどこかで引数オブジェクトを使用しない限り、ほとんどのブラウザーは実際には引数オブジェクトを作成しません(return
)の後でも。arguments
これが、参照されると、それを含む行が実行されない場合でも、パフォーマンスが低下する理由です。
eval
ECMA-262標準の§10.4.2で指定されているeval
ようにコードを入力するには、特別な実行コンテキストを作成する必要があります。基本的に、呼び出し元の関数の実行コンテキストのすべてのプロパティをコンテキストにバインドする必要があります。eval
1つの関数で複数eval
のが呼び出された場合、基本的に両方が同じプロセスを2回実行します。最適化のために、ブラウザがeval
関数にが含まれていることを検出すると(の後でさえreturn
)、すべてが使用できるこの新しい実行コンテキストを事前に入力eval
するため、何度も再作成する必要はありません。
これらの最適化はブラウザに依存し、標準では必要とされないため、一部のブラウザは説明されている最適化を実際に実行しない場合や、動作が異なる場合があることに注意してください。