eval 関数はパラメータ s を受け取ります。s が文字列でない場合は、s を直接返します。それ以外の場合は、s ステートメントを実行します。 s ステートメントの実行結果が値の場合はその値が返され、それ以外の場合は未定義が返されます。
オブジェクト宣言構文「{}」は値を返せないことに注意してください。値を返すには括弧で囲む必要があります。
var code1='a" 2' //Expression
varcode2; ='{a:2}'; //ステートメント
alert(eval(code1)); //->'a2'
alert(eval(code2)); //-> >alert(eval('(' code2 ')')); //->[object Object]
ご覧のとおり、オブジェクト宣言ステートメントの場合のみ実行されます。値を返すことはできません。一般的に使用される「{}」オブジェクト宣言ステートメントを返すには、値を返す前にステートメントをかっこで囲んで式に変換する必要があります。これは、Ajax 開発で JSON を使用する基本原則の 1 つでもあります。この例では、2 番目のアラート ステートメントは未定義を出力し、括弧を追加した後の 3 番目のアラート ステートメントはステートメントで表されるオブジェクトを出力することが明確にわかります。
次に、この記事の焦点である関数内でグローバル コードを実行する方法について説明します。この問題を説明するために、例を見てみましょう:
var s ='global'; // グローバル変数を定義します
function Demon1(){
eval('var s="local"');
}
demo1(); 🎜>alert( s); //->global
は、次の関数と同等です。 function Demon1(){var s='local'; }、ローカル変数 s を定義します。
結局のところ、最終的な出力がグローバルであることは驚くべきことではありません。ローカル変数とグローバル変数は誰でも明確に区別できます。
注意深く体験すると、eval 関数の特徴がわかります。これは、変数定義であっても、呼び出されるコンテキスト変数空間 (パッケージ、クロージャーとも呼ばれます) 内で常に実行されます。コードは未定義関数エラーを生成します:
var s= 'function test(){return 1;}' //関数定義文
function Demon2(){
eval(s);
demo2();
alert(test()); //->エラー: テストが定義されていません
これは、テスト関数がローカル空間で定義されているためです。は、demo2 関数内でアクセスできますが、外部からはアクセスできません。
実際の Ajax 開発では、一度に大量のコードをロードする問題を軽減するために、実行のためにサーバーからコードを動的に取得する必要がある場合や、一部のコードが Javascript 自体によって生成されるため、その eval 関数を使用する必要がある場合があります。実行。
しかし、このような動的コードの取得は通常、関数内で行われます。たとえば、次のようになります。
varcode=getCode();
eval(code);
}
eval であることがわかります。グローバル空間で実行することはできません。これは開発に多くの問題をもたらし、多くの人がこれに不満を感じているのを見てきました。
しかし、ついに解決策を見つけました。へー、IE と Firefox を同時に互換できるのです。その方法は次のとおりです。
コードをコピーします。 🎜>
//つまり
execScript(code)
}else{
//つまり
window.eval(code); );
}
}
関数内でグローバル コードを定義する場合は、次の例のように X2.eval_r(code) メソッドを呼び出すことができます。 🎜>
コードをコピーします
demo3 関数でグローバル変数 s="local" が再定義されていることがわかります。
X2.Eval は値を返さないことに注意してください。式を評価したい場合は、システムの eval 関数を使用する必要があります。 X2.Eval は、グローバル コード定義のみに使用されるように設計されています。
実際、これを見た後、問題を解決するのが簡単すぎると感じる人もいるかもしれません (笑)、しかし、この方法を見つけるには、ある程度の運とスキルが必要です:
(1) IE ブラウザの場合、これはすでに提供されています。デフォルトの関数: execScript。グローバル空間でコードを実行するために使用されますが、それについて知っている人はあまりいません。
(2) Firefox ブラウザの場合、eval 関数が直接呼び出された場合は呼び出し元の空間で実行され、window.eval が呼び出された場合はグローバル空間で実行されます。おそらくこれを知っている人はさらに少ないでしょう。結局のところ、alert(eval==window.eval) は true を返します。
Firefox の eval 関数の特性は確かに非常に奇妙ですが、そのソースは JavaScript 仕様にも記載されています:
eval プロパティの値が直接呼び出し以外の方法で使用されている場合 (つまり、他の方法で使用されている場合) CallExpression の MemberExpression である識別子としてその
名を明示的に使用するよりも)、または eval プロパティが割り当てられている場合、
EvalError 例外がスローされる可能性があります。
その意味について。つまり、eval 関数の実行は呼び出し元に関連していますが、その実行コンテキストには問題はありません。したがって、IE と Firefox のどちらが正しいか間違っているかを言うのは難しいのですが、誰もが解決策を知っているのは良いことです。