2013-04-11 1 views
0

У меня есть вызов Eval() в глобальном контексте с таким кодом:Странное поведение eval() в глобальном контексте и в контексте функции. Функция IE9 и IE10

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");. Любые комментарии приветствуются?

ответ

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 

у нас есть доказательства

  • Вы правильно - «это» в функции «глобальная это», а «это» в методе нет. Таким образом loadLib() имеет доступ к глобальному контексту.
  • Концептуально, eval напоминает ввод кода вручную, а не вызов функции.
  • При написании/оценке goLib1 = {'name' : 'lib1', ... (in) непосредственно в loadLib() вы изменяете глобальный контекст, потому что значение var, которого нет (очевидно, случай для лингвистов, философов или сжимается), «пожалуйста, поставьте эта переменная в это ».
  • При написании/оценке function f1() { ... (in) непосредственно в loadLib() вы делаете то же самое, что и при написании function flocal() { ... - вы определяете функцию local для loadLib(), которая не должна быть (и не) видна из loadLib().
  • Если вы хотите выполнять функции из библиотеки, доступной из функции «снаружи», вы можете использовать назначение как this.f1 = f1; - все это, потому что это не «локальное» ключевое слово в сценарии J (ava), которое вы могли бы drop, чтобы сделать функции глобальными.
  • или наоборот.
+0

Спасибо. Вы правы, все в контексте. – 23W