使用eval()从作用域中的对象变量中提取数据

3

我该如何将一个字符串作为代码执行(使用 eval()),并给它一些变量?例如,我有一个名为 vars 的对象,并希望代码能够访问其每个属性,而不需要明确指定对象的名称。类似这样:

function evalWithVariables(func, vars) {
 //some magic here
 return eval(func);
}

function test() {
 var retval = evalWithVariables("a>5", {"a":7});
 console.log(retval);
}

噢,而且这段代码是可信的,它来自于与脚本相同的服务器,不是用户生成的,我很确定 eval 是这里正确的工具(我知道 eval 经常被认为是邪恶的)。

编辑: 对我来说最重要的是,传递给 eval() 的代码看起来好,并且短小精悍,不必包含助手变量名等。

4个回答

5

发现可以仅使用with

eval("with (vars) {var result = (" + func + ")}");

1
请注意,在严格模式下不允许使用with()。 - Okku

2
您可以将这些值重新组合成JavaScript代码,并将其作为要执行的代码的前置代码。然后,将实际表达式的结果分配给一个本地变量。因此,
evalWithVariables("a>5", {"a":7});

实际上进行了eval操作:

var a=7; var result = (a>5);

然后,在eval之后,检查result的值:

function evalWithVariables(func, vars) {
 var varString = "";

 for (var i in vars)
     varString += "var " + i + " = " + vars[i] + ";";   

 eval(varString + "; var result = (" + func + ")");
 return result;
}

1
这个概念本身就很模糊 :) - Chris Laplante

1
放弃使用 eval() 的一个选择是生成一个函数,然后使用 with() 来改变块级作用域,就像你所做的那样:
function evalWithVariables(func, vars) {
    return new Function("v", "with (v) { return (" + func +")}")(vars);
}

这难道不比我的解决方案更加复杂和缓慢吗? - thejh

0

也许您可以采用更加函数式的方式:

function evalWithVariables(func, vars) {
    return func(vars);
}
evalWithVariables(function(vars) { return vars.a > 5; }, {"a":7})

或者更简短点:

(function(vars) { return vars.a > 5; })({"a":7})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接