问题
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