我如何dynamic地在node.js中的当前作用域中dynamic创build一个variables?

我试图dynamic创build指向对象的node.jsvariables。

我知道我可以使用evaldynamic创build一个variables:

var vars = ['a','b'] for(var n=0; n<vars.length; n++) { eval('var '+vars[n]+' = '+n) } console.log(b) // prints 1 

上面的代码dynamic地创build了variables,并给它们赋值了vars列表中的任何索引。

但是如果我想将这些dynamicvariables设置为对象引用呢? 像下面这样:

 var vars = {a: {}, b:{}} for(var k in vars) { eval('var '+k) // create the variable dynamically new Function('value', k+' = value')(vars[k]) // attempt to set the value } ab = 5 console.log(vars.ab) // undefined : ( 

我知道为什么上述不起作用 – 由new Function函数创build的new Function不能看到当前范围,所以不能设置值。 有没有办法做我想做的事情,这样console.log(vars.ab)会打印“5”,而不是“undefined”?

更新:

嗯,我错了, new Function无法看到或修改本地范围内的variables,因为这个工程:

 var obj = {} eval('var x') new Function('value', 'x = value')(obj) obj.a = 5 console.log(xa) // prints 5 

所以现在我很困惑为什么我的循环以上似乎不工作..

更新2:

我只是意识到我的代码实际上在Chrome的控制台工作。 但它不能在node.js中工作…

更新只是菲尔:

这是我的情况。 我使用Parsimmon来构buildparsing器组合器。 这是如何完成的:

 var L = Parsimmon.createLanguage({ combinator1: function() { return Parsimmon.string('hi') }, combinator2: function() { return L.combinator1.many() } }) 

我希望在我编写每个parsing器组合器之前,不需要写L. 我可以这样做:

 var combinator2 = L.combinator2 

但是,这将需要我为我写的每个combinator添加一个额外的行。 正如你所看到的,我不能使用with因为L是在我可以写with(L)之后创build的,如果我在下面定义我的函数然后在对象中使用它们,我回来复制这些函数名每次我写一个新的combinator。

所以总结一下,我想通过L循环,并把所有生成的parsing器组合器放在一个很好的干净的variables范围内,所以我可以写combinator1而不是L.combinator1 (etc)。

IIUC,无论是否有更好的方法来实现你的目标,如果你只是在dynamicFunction删除'var ' ,它将在外部(全局)范围上操作。

更改:

 new Function('value', k+' = value')(vars[k]) 

至:

 new Function('value', k+' = value')(vars[k]) 

所以:

 var vars = {a: {}, b:{}} for(var k in vars) { eval('var '+k) // create the variable dynamically new Function('value', k+' = value')(vars[k]) // attempt to set the value } ab = 5 console.log(vars.ab) 

你不想在函数内部声明一个局部范围的新variables,你想在外部范围上操作。

更新来解决新的问题

你的第一个循环确实有效。 试着反思ab ; 他们分别是0和1。

根据信息更新2,这是为Node.js

根据https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FunctionFunction始终在全局范围内工作。 在Node中,这是globalvarvariables不是全局作用域,而是模块的作用域。 为了解决这个节点,你可以做下面的事情,并省略你的eval var声明(这是重写模块的全局范围,你可以访问Function ):

 var vars = {a: {}, b:{}} for(var k in vars) { new Function('value', k +' = value')(vars[k]) // attempt to set the value } ab = 5 console.log(vars.ab) // 5 

换句话说,内部函数设置的variables可以通过global自动访问,所以你的模块代码,在没有任何覆盖全局的模块范围的var声明的时候,你可以设置全局的a属性,就像ab = 5

更新3

由于我刚刚在理解Function解决了你的问题,所以我给了上面的信息。 根据你的后续评论(再次,没有说明它是否适合你的特定用例),你可以通过eval对对象进行操作,如下所示:

 var vars = {a: {}, b:{}} for(var k in vars) { eval('var '+k+' = vars["'+k+'"]') } ab = 5 console.log(vars.ab) // 5 

改变这一行:

 from : ab = 5 to vars.ab = 5 

因为a在你的情况下是未定义的,这就是为什么现在允许创build一个新的属性

vars.a将返回一个对象,不仅是一个variables属性。