1

このようなコードを使用して、グローバルコンテキストで eval() 関数を呼び出しました。

eval( (new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile("/BaseScripts/sft.js", 1).ReadAll(),  );

その後、「sft.js」スクリプト ファイル内のすべてのローカル変数、関数、オブジェクトがグローバル コンテキストに追加されます。しかし、ローカル関数で行う eval の同じ呼び出しの場合:

function run_eval(path) {
   eval( (new ActiveXObject("Scripting.FileSystemObject")).OpenTextFile(path, 1).ReadAll(),  );
}

run_eval("/BaseScripts/sft.js");

「sft.js」スクリプト ファイル内のローカル変数、関数、オブジェクトは、グローバル コンテキストに追加されません。なんで ?ドキュメントによると、両方の呼び出しはグローバルオブジェクトに対して確立されていますなぜ最初の呼び出しだけが "sft.js" スクリプト ファイルからグローバル オブジェクトに変数を追加するのですか? 状況を保存せずrun_eval()、グローバル コンテキストで明示的に呼び出します。

   run_eval.call(this, "/BaseScripts/sft.js");
   //or
   run_eval.call(RuntimeObject(), "/BaseScripts/sft.js");

両方の呼び出しは結果によって等しいrun_eval("/BaseScripts/sft.js");です。コメントは歓迎ですか?

4

1 に答える 1

1

このライブラリ (lib1.js) の場合:

// no "var" variables go into the GLOBAL OBJECT/SCOPE
goLib1 = {'name' : 'lib1', 'version' : '0.01', 'check' : function() {return goRoot === this;}};

// functions go into the CURRENT OBJECT/SCOPE
function f1() {
  return "f1";
}

function f2() {
  return "f2";
}

、このメイン スクリプト (main.js):

// globals (no "var" + prefix to leave no room for doubt
goFS  = new ActiveXObject("Scripting.FileSystemObject");
goRoot = this;
goAct = "TopLevelEval";
//goAct = "EvalInFunction";

// should be variadic
function print(x) {
  WScript.Echo(x);
}

// 'import' a library/module; hint wrt 'export'
function loadLib(lib) {
  function flocal() {
    return "I'm a local function in function loadLib()";
  }
  eval(goFS.OpenTextfile(lib).ReadAll());
  print("in loadLib: f(1) => " + f1() + " f2() => " + f2());
  print("flocal() = " + flocal());
  print("goRoot === this: " + (goRoot === this));
  // 'export' function(s)
  //this.f1 = f1;
  goRoot.f1 = f1;
}

print(goAct);
if (goAct == "TopLevelEval") {
  eval(goFS.OpenTextfile(".\\lib1.js").ReadAll());
} else {
  loadLib(".\\lib1.js");
}

print("loaded library " + goLib1.name + " v. " + goLib1.version + " 'goRoot === this'-check: " + goLib1.check() + 

")");
print("typeof f1: " + (typeof f1));
print("typeof f2: " + (typeof f2));
print("typeof flocal: " + (typeof flocal));

、出力 "TopLevelEval":

TopLevelEval
loaded library lib1 v. 0.01 'goRoot === this'-check: false)
typeof f1: function
typeof f2: function
typeof flocal: undefined

、および出力 "EvalInFunction":

EvalInFunction
in loadLib: f(1) => f1 f2() => f2
flocal() = I'm a local function in function loadLib()
goRoot === this: true
loaded library lib1 v. 0.01 'goRoot === this'-check: false)
typeof f1: function
typeof f2: undefined
typeof flocal: undefined

私たちは証拠を持っています

  • その通りです。関数内の「this」は「グローバル this」ですが、メソッド内の「this」はそうではありません。したがって、 loadLib() はグローバルコンテキストにアクセスできます
  • 概念的には、eval は関数呼び出しではなく手でコードを入力したようなものです。
  • goLib1 = {'name' : 'lib1', ...loadLib() に直接 (in)書き込み/評価することにより、グローバル コンテキストが変更されます。varこれは、存在しない の意味 (明らかに言語学者、哲学者、またはシュリンクのケース) が「この変数をこれに入れてください」であるためです。 .
  • function f1() { ...loadLib() に直接書き込み/評価することで、書き込みと同じことを行いfunction flocal() { ...ます。loadLib() の外では見えてはならない (そして見えない) loadLib() に対してローカルな関数を定義します。範囲。
  • ライブラリの関数をインポート関数の「外側」からアクセスできるようにしたい場合は、次のような割り当てを使用できます。this.f1 = f1;これはすべて、J(ava)script の「ローカル」キーワードではないため、関数を作成するためにドロップできるためです。グローバル。
  • またはその逆。
于 2013-06-14T15:02:56.387 に答える