ホームページ  >  記事  >  ウェブフロントエンド  >  javascript_javascriptスキルにおけるevalとwithの使用例まとめ

javascript_javascriptスキルにおけるevalとwithの使用例まとめ

WBOY
WBOYオリジナル
2016-05-16 15:28:481222ブラウズ

この記事の例では、JavaScript での eval と with の使用法について説明します。参考のために皆さんと共有してください。詳細は次のとおりです:

JavaScript のスコープ メカニズムは誰もが知っていますが、with と eval はスコープについての従来の理解を「破壊」することがあります。 eval と with の使用法について、オンライン リソースと自分自身の理解を参考にまとめてみましょう。

1. 評価

1. eval 関数: 文字列を JS 式として処理して実行します。 2. 構文: eval(strScript) 注: パラメーター strScript は必須です

3. 使用説明書

(1) 戻り値を持ちます。パラメータ文字列が式の場合、その式の値が返されます。パラメータ文字列が式ではなく、値がない場合は、「未定義」が返されます。

(2) パラメータ文字列がコードとして実行される場合、パラメータ文字列は eval 関数が呼び出されるコンテキストに関連します。つまり、パラメータ文字列に表示される変数または関数呼び出しは、eval が呼び出されるコンテキストで使用可能でなければなりません。


4. 例:

function $(s) { if (document.getElementById) { return eval('document.getElementById("' + s + '")'); } else { return eval('document.all.' + s); } } //eval,这个比较常用
var myTest = function() { return "eval test"; };
function evalTest() {
  //简单数据
  alert(eval("1+1")); //2
  alert(eval("'a'+1")); //a1
  alert(eval("1+'a'")); //1a
  alert(eval("parseInt('a'+1)")); //NaN
  alert(eval("parseInt(1+'a')")); //1
  alert(eval("true")); //true
  alert(eval("0==false")); //true
  alert(eval("1==undefined")); //false
  alert(eval("isNaN(undefined)")); //true
  //函数和对象
  alert(eval("this")); //[object]
  alert(eval("typeof(this)")); //object
  alert(eval("typeof(test)")); //undefined
  alert(eval("evalTest")); //这个显示当前函数的定义语句细节,包含注释
  //alert(eval("evalTest()")); //调用自己并执行,这个会有大问题啊!
  alert(eval("typeof(evalTest)")); //function
  //其他
  var tmpFunc = "{a:1}";
  alert(eval(tmpFunc)); //1
  alert(eval("(" + tmpFunc + ")")); //[object object]
  alert(eval("tmpFunc")); //{a:1}
  //alert(eval("tmpFunc()")); //脚本错误
  alert(myTest());
  eval("alert(myTest())"); //和上面等价
  alert(eval(myTest));
  alert(eval("myTest")); //和上面等价
  //form里的一个input,id=txtUserName
  eval("$('txtUserName').value='jeff wong';"); //等价于 $('txtUserName').value = 'jeff wong';
  eval("alert( $('txtUserName').value);");
}
evalTest(); 

5、評価とスコープ

(1) 古典的なコード分析

a.共通

var str = "global";
function test() {
  alert(str); //undefined
  var str = "local";
}
test();
alert(str); //global

分析: 予想通り、指定した値が得られました。テスト関数の str の結果も var なしと var 宣言で異なります。読者は自分で検証できます。

b、変数を直接宣言する代わりに eval

var str = "global";
function test() {
  alert(str); //??
  eval("var str='local';");//会像我们预期的那样吗?
  //var str = "local";
  alert(str); //这里又是什么结果?
}
test();
alert(str); //??

分析: aの書き方と比較すると、テスト関数内でvarを直接宣言する文をeval文で置き換えて変数を定義し、最後にalertを出すだけで結果は大きく異なります。

(2) eval はグローバル コードを定義します

a. IE および FF と互換性があり、グローバル コードを定義する eval 関数

var nav = new Object();
//通用eval函数
nav.Eval = function(jsCode) {
  if (document.all) //IE下是execScript
   execScript(jsCode);
  else window.eval(jsCode); //FF下是window.eval
}

IE ブラウザの場合、関数 execScript はグローバル空間でコードを実行するために使用されます。
Firefox ブラウザの場合、eval 関数が直接呼び出された場合は呼び出し元のスペースで実行されますが、window.eval が呼び出された場合はグローバル スペースで実行されますが、戻り値はalert(eval==window. eval) は true ですが、これは奇妙なことです。


b.

のテスト コードを呼び出します。

var nav = new Object();
//通用eval函数
nav.Eval = function(jsCode) {
  if (document.all) //IE下是execScript
   execScript(jsCode);
  else window.eval(jsCode); //FF下是window.eval
}
function test() {
  nav.Eval("var str = 'global';"); //这里声明变量str,在外面的函数中可以调用变量
  nav.Eval("var tmpFunc = function(){alert('global function');};"); //这里声明函数变量tmpFunc,在外面的函数中可以调用函数
  alert(str); //global
  tmpFunc(); //global function
}
test();
alert(str); //global (调用nav.Eval函数声明的全局变量)
tmpFunc(); // global function (调用nav.Eval函数声明的全局函数)

分析: b のコードを通して、グローバル コードを定義する eval の明らかな不便さを発見したかもしれません。つまり、グローバル コードの場合、JS スマート プロンプト (ここでは vs や他のツールも同様) のプロンプト機能が完全に失われます。 。このことから、eval を介してプログラム内に多くのグローバル コードが定義されている場合、その保守性は低すぎるのではないかと疑問に思うでしょう。私の意見は、インターネット上の要約に同意し、eval の使用を減らすということです。結局のところ、既製のツールでは適切なプロンプトを提供することはできませんし、プログラマーの視力もそれほど優れていないことがよくあります。

2.

1.

with ステートメント: 1 つまたは複数のステートメントのデフォルト オブジェクトを指定します。通常、特定の状況で記述しなければならないコードの量を短縮するために使用されます

2. 文法: with (273238ce9338fbb04bee6997e5552b95) fa7ef95fdb8b7324b4f19dcbb8e23063 with (オブジェクト)
ステートメント
(1) パラメータオブジェクト: 新しいデフォルトオブジェクト
(2) ステートメント: 1 つ以上のステートメント。オブジェクトはステートメントのデフォルトのオブジェクトです。

3. 例:

function withTest() {
 with (document) { //document的重复使用
 writeln("Hello,");
 writeln("it's a with keyword test!");
 }
 with (Math) { //Math的重复使用
 alert(random());
 alert(abs(-10));
 }
}
withTest();

4. を使用すると、スコープ チェーンが一時的に変更されます

function withTest() {
 var userName = "jeff wong";
 //暂时修改作用域链
 with (document) {
 writeln("Hello,");
 writeln(userName);
 }//with内的语句执行完之后,作用域链恢复原状
 alert(userName);
}
withTest();

分析: withTest 関数が定義されると、withTest のスコープ チェーンが決定され、このスコープ チェーンの先頭が window オブジェクトであると仮定します。withTest が実行されると、JS エンジンは呼び出しオブジェクト (呼び出しオブジェクト) を生成します。 ) をスコープ チェーンの最後 (ウィンドウ オブジェクトの後) に追加します。ステートメントが with(document) まで実行されると、新しいスコープが生成されます (本質的に、このスコープは通常の関数のスコープと同じです)。ただし、with 句が実行されるとスコープは消えます) がスコープ チェーンの最後に追加されるため、with 内の変数を検索する場合は、このチェーンの with (ドキュメント) スコープが優先されます。 、次に withTest の呼び出しオブジェクトから検索し、最後に window を検索します。 with 内のステートメントが実行された後、スコープ チェーンは元の状態に復元されます (with(document) によって生成されたスコープはスコープ チェーンの外に移動されます)。

ps: with はスコープ チェーンの操作 (スコープの内外への移動) が必要となり、実行効率が低くなるため推奨されません。

この記事が JavaScript プログラミングのすべての人に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。