我认为这在技术上是设计使然的(请参见有关类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)
中声明任何东西,而其他所有变量声明都有。令人尴尬的是,直到我遇到这个问题之前,我认为类只是函数的语法糖,但显然比这复杂。 ?
答案 0 :(得分:0)
我在这个问题上取得了一些进展-正如@Bergi指出的那样:
问题在于,eval确实为词汇声明创建了新范围(就像一个块一样),因此
let
,const
和class
成为{内的局部变量{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 {}