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");

两个调用都等于 equ by result to 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 就像手动输入代码而不是函数调用。
  • 通过直接在 loadLib() 中写入/评估goLib1 = {'name' : 'lib1', ...(in),您可以更改全局上下文,因为varwhich 不存在的含义(显然是语言学家、哲学家或收缩者的情况)是“请将此变量放入 this” .
  • 通过直接在 loadLib() 中写入/评估function f1() { ...(in),您可以执行与写入相同的操作function flocal() { ...- 您定义了 loadLib() 的本地函数,它不应该(也不)在 loadLib() 中可见范围。
  • 如果你想让库中的函数可以从导入函数的“外部”访问,你可以使用这样的赋值this.f1 = f1;- 所有这些,因为 J(ava)script 中没有“local”关键字,你可以删除它来创建函数全球的。
  • 或相反亦然。
于 2013-06-14T15:02:56.387 回答