「エイリアス」eval
を使用して、同じように動作することを期待することはできません。そのような単純な。なんで?eval
関数ではありません。
何が起こっているかというと、 を呼び出すときにeval2
、変数「キャッシュ」を設定してグローバル変数を操作するということです。したがって、その中に変数を設定することで、グローバル変数を設定しています。ただし、終了すると、変数「キャッシュ」は関数スコープのものに戻ります。2 番目alert
が 1 を示しているのはそのためです。グローバル変数は関数レベル 1 によって隠されています。
これは、ECMAScript (強調鉱山) の付録 E (239 ページ) に記載されています。
10.4.2: 第 5 版では、eval 関数への間接呼び出しは、eval コードの変数環境とレキシカル環境の両方としてグローバル環境を使用します。Edition 3 では、間接 eval の呼び出し元の変数および字句環境が、eval コードの環境として使用されました。
「評価コードの入力」に関する完全な定義は、§10.5.2 (page 58) で定義されています (強調は私のものです)。
- 呼び出しコンテキストがない場合、またはeval 関数への直接呼び出し (15.1.2.1.1)
によって eval コードが評価されていない場合、
- 10.4.1.1 で説明されているように、eval コードを C として使用して、グローバル実行コンテキストであるかのように実行コンテキストを初期化します。
- そうしないと、
- ThisBinding を、呼び出し元の実行コンテキストの ThisBinding と同じ値に設定します。
- LexicalEnvironment を呼び出し実行コンテキストの LexicalEnvironment と同じ値に設定します。
- VariableEnvironment を呼び出し実行コンテキストの VariableEnvironment と同じ値に設定します。
- eval コードが厳密なコードの場合、
- 引数として LexicalEnvironment を渡して NewDeclarativeEnvironment を呼び出した結果が strictVarEnv であるとします。
- LexicalEnvironment を strictVarEnv に設定します。
- VariableEnvironment を strictVarEnv に設定します。
- eval コードを使用して、10.5 で説明されているように宣言バインディングのインスタンス化を実行します。