eval()在全局上下文和函数上下文中的奇怪行为。 IE9& IE10

时间:2013-04-11 07:00:22

标签: javascript internet-explorer-9 jscript

我在全局上下文中使用以下代码调用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”脚本文件中的局部变量,函数,对象不会添加到我的全局上下文中。为什么?根据文档,这两个调用都是在全局对象中建立了 this 。为什么只有第一次调用会将“sft.js”脚本文件中的变量添加到全局对象?不要保存这种情况,并在全局环境中明确调用run_eval()

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

两次调用都是run_eval("/BaseScripts/sft.js");的结果。 欢迎提出任何意见吗?

1 个答案:

答案 0 :(得分: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

我们有

的证据
  • 你是对的 - "这"在一个函数中是' global this',而" this"在一个方法中是不是。因此loadLib()可以访问全局上下文
  • 从概念上讲,eval就像是手动输入代码而不是函数调用。
  • 通过直接在loadLib()中编写/评估goLib1 = {'name' : 'lib1', ...(in),您可以更改全局上下文,因为var的含义不存在(显然是语言学家的情况) ,哲学家,或收缩)是#34;请把这个变量放到这个"。
  • 通过直接在loadLib()中编写/评估function f1() { ...(in),你可以像写function flocal() { ...一样 - 你定义了一个本地的函数loadLib(),这不应该是从loadLib()的范围中可以看到(并且没有)。
  • 如果您想通过导入功能访问库中的功能,可以使用this.f1 = f1;之类的作业 - 所有这一切,因为不是& #39;地方' J(ava)脚本中的关键字,您可以将其删除以使函数成为全局函数。
  • 或反之亦然。