在JavaScript中指定eval()的范围?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

有没有什么办法可以在特定范围(但不是全局的)上执行eval(

例如,以下代码不起作用(第二条语句中的a未定义),因为它们在不同的范围内:

eval(var a = 1); 
eval(alert(a));

如果可能的话,我想在飞行中创建一个范围。例如(语法肯定是错误的,但只是为了说明这个想法)

var scope1;
var scope2;
with scope1{
    eval(var a = 1); eval(alert(a));  // this will alert 1
}
with scope2{
    eval(var a = 1); eval(a++); eval(alert(a));  // this will alert 2
}
with scope1{
    eval(a += 2); eval(alert(a)); // this will alert 3 because a is already defined in scope1
}

任何想法如何实现这样的事情?谢谢!

提问于
用户回答回答于

在你的范围中创建你想存在的变量作为函数中的局部变量。然后,从该函数返回一个本地定义的函数,该函数只有一个参数并对其进行调用eval。该实例eval将使用其包含函数的作用域,它嵌套在顶级函数的范围内。顶层函数的每次调用都会创建一个新的作用域,并带有eval函数的新实例。为了保持一切动态,您甚至可以使用eval顶级函数中的调用来声明对该范围本地的变量。

示例代码:

function makeEvalContext (declarations)
{
    eval(declarations);
    return function (str) { eval(str); }
}

eval1 = makeEvalContext ("var x;");
eval2 = makeEvalContext ("var x;");

eval1("x = 'first context';");
eval2("x = 'second context';");
eval1("window.alert(x);");
eval2("window.alert(x);");

https://jsfiddle.net/zgs73ret/

用户回答回答于

您可以使用"use strict"在eval本身中包含已评估的代码。

其次,eval严格模式代码不会向周围范围引入新变量。在正常的代码中,eval("var x;")将变量x引入周围的函数或全局范围。这意味着,一般来说,在一个包含对eval每个不涉及参数或局部变量的名称的调用的函数中,必须在运行时将其映射到特定的定义(因为eval可能引入了一个隐藏外部变量的新变量)。在严格模式下,eval仅为正在评估的代码创建变量,所以eval不能影响名称是指外部变量还是某个局部变量

var x = 17;                                       //a local variable
var evalX = eval("'use strict'; var x = 42; x");  //eval an x internally
assert(x === 17);                                 //x is still 17 here
assert(evalX === 42);                             //evalX takes 42 from eval'ed x

如果一个函数声明为“use strict”,则其中的所有内容都将以严格模式执行。以下内容与上述内容相同:

function foo(){
    "use strict";

     var x = 17;
     var evalX = eval("var x = 42; x");
     assert(x === 17);
     assert(evalX === 42);
}

扫码关注云+社区