可以使用eval声明多个全局类吗?

时间:2020-06-12 01:00:31

标签: javascript

我认为这在技术上是设计使然的(请参见有关类here的表达式与声明的讨论),但是我找不到找到使用eval来使全局类声明按预期工作的方法。全局函数声明没有问题。实际上,这是我第一次看到eval(...)产生与仅将代码直接嵌入文件不同的系统状态。

例如:

// SHOULD declare global window.GlobalTest
class GlobalTest {}

// no problem!
console.log({ GlobalTest });

// SHOULD declare window.A, and window.B
eval('function A(){} function B(){}');

// no problem!
console.log({ A, B });

// SHOULD declare window.EvalTest
eval('class EvalTest {};');

// uh-oh! EvalTest is undefined =(
console.log(`typeof EvalTest: ${typeof EvalTest}`);


/* THINGS THAT WORK */

// single expression + assignment (boo!)
let SingleExpression = eval('(class SingleExpression {})');
console.log({ SingleExpression });

// assignment (boo!)
eval('AssignmentExpression = class {}');
console.log({ AssignmentExpression });

在全局范围内运行eval,我们可以声明多个顶级函数而不会出现问题。但是,的工作方式有所不同-似乎只能通过分配eval(即EvalTest = class {})来使用eval(...)声明全局类,但这需要处理代码而不是它只是...工作。

另一种方法是完全隔离类,将其包装在括号中以使其成为表达式,然后分配SingleExpression调用的结果(例如,请参见class GlobalTest {})。这似乎很奇怪,因为在全局范围内,在我测试过的任何环境中,我们都可以使用eval声明类。但是在eval内部,它分崩离析。无论如何,这也需要对代码进行预处理。

我有一个包含多个类和函数的脚本,除非我对代码 just进行预处理,否则似乎无法按预期方式运行它并通过一个class MyGlobalClass {}调用来声明多个全局类。 em>,以便eval正常工作。全局函数/对象声明不是问题。

我在这里缺少明显的东西吗?任何意见,将不胜感激。我知道-“这不是错误,它是一个功能”-但似乎奇怪的是,类声明实际上没有在linalg.norm(y-z)声明任何东西,而其他所有变量声明都有。令人尴尬的是,直到我遇到这个问题之前,我认为类只是函数的语法糖,但显然比这复杂。 ?

1 个答案:

答案 0 :(得分:0)

我在这个问题上取得了一些进展-正如@Bergi指出的那样:

问题在于,eval确实为词汇声明创建了新范围(就像一个块一样),因此letconstclass成为{内的局部变量{1}}个代码。

http://www.ecma-international.org/ecma-262/#sec-performeval

eval

因此,在大多数传统的运行时中,没有没有这种方法,除非先关闭编译代码(这自然会将全局范围内的词法重新定义为eval("var a = 1; let b = 2; class c {}"); console.log(typeof a, typeof b, typeof c);形式)

但是,我正在使用NodeJS,看来vm.Script.runInThisContext可以用来按预期方式编译代码:

var c = class {}