Creating class with vm.runInNewContext (forcing class expression instead of class declaration in ES6)

纵饮孤独 提交于 2021-01-28 06:27:09

问题


I am debugging another person's package (currently unmaintained) that runs in the Atom editor. At one point, this package uses vm.runInContext to define a class object, using code equivalent to the following:

const vm = require('vm')
myClass = vm.runInNewContext('class x {}', {}, 'file')

I think this code runs in node.js, but I don't really know all the details of Atom's javascript environment. At any rate, I'm pretty sure it's running in ES6 or later. I believe that when this package was last updated in April 2017, the call to vm.runInNewContext returned a valid class object. However, it currently returns undefined, probably due to some upgrade in Atom since then (maybe around June 1, 2018). Because of this, references to attributes of myClass now fail, which is the bug I am trying to fix.

I believe what is happening here is that javascript interprets the class x {} code as a class declaration, which has no value, so vm.runInNewContext returns undefined. So I'm looking for a graceful way to force this code to return a class, rather than undefined. I have found the following possibilities:

// add a reference to the class, which will be returned as the final value
vm.runInNewContext('class x {}; x', {}, 'file')

// use an assignment, which treats this as a class expression, 
// then the assignment is returned as the final value
vm.runInNewContext('var x; x = class x {}', {}, 'file')
// note: a simpler version ('var x = class x {}') returns undefined

// wrap the class statement in parentheses, so it is evaluated as
// a class expression instead of a class declaration
vm.runInNewContext('(class x {})', {}, 'file')

All of these work, but they all seem clunky. Is there some "standard" way to force javascript / ES6 to treat class x {} as a class expression rather than a class declaration?


回答1:


This behaviour isn't specific to Node.js vm.runInNewContext. The code should be forced to be evaulated as expression.

eval('function foo () {}') === undefined

because it's treated as function declaration instead of function expression. For the same reason this line will result in syntax error:

function () {};

It isn't valid function declaration and it's not used as expression.

So parentheses

vm.runInNewContext('(class x {})', {}, 'file')

or comma operator

vm.runInNewContext('0, class x {}', {}, 'file')

are conventional ways to make evaluated code an expression.



来源:https://stackoverflow.com/questions/51486025/creating-class-with-vm-runinnewcontext-forcing-class-expression-instead-of-clas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!