JavaScript中eval()的替代方法

34

我主要使用javascript、Jquery、knockout等技术进行工作。

吸引我使用eval()的原因是

var a = 5;
var b = 10;
eval("a+b");
//Gives me output 15

注意:我处理的案例中,ab 的值会动态变化。

在我的工作中,我需要处理来自Json、Knockout等的大量动态对象。因此,eval函数可以解决我的大部分问题。 但是,我发现eval()存在许多问题,例如减速等。

我进行了许多搜索,没有找到任何替代eval()的方法,当我需要将以字符串形式获取的方程式求值为对象时。

有人能推荐一个插件或函数,替代eval(),并考虑到我上面给出的例子吗?

问题:

我使用knockout映射从Json数据创建表格,以便无论Json的格式如何,都可以生成表格。我还使用knockout computed计算一些字段。 目前,我使用硬编码。

self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })
self.salaryEqn(salEqnTxt); 

我想动态地执行这些方程。我可以将它们动态创建为字符串,但评估它们是我面临的问题。

我想要解决方案:

是否有一种方法可以在JavaScript中计算存储在字符串中的公式而不使用eval?

就像一个公式

 "self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })"

2
通常情况下,应尽可能避免使用eval()。使用eval()时可能会遇到以下问题,请查看以下链接:http://ajaxmin.codeplex.com/wikipage?title=Problems%20with%20Evals 更新:请参考此stackoverflow答案了解javascript中eval的替代方案。 - RGR
2
a + b 可以直接得到 15,而不需要将其表示为字符串然后进行 eval。 - Quentin
@ClaudioRedi这样做会得到与eval("a+b")相同的结果吗? - Okky
@Okky - 问题在于您将问题简化得太多,以至于我们无法确定它是什么。您的问题是“如何解决X,可以通过eval解决,而不使用eval?”我们没有足够的信息来理解X是什么。 - Quentin
@Okky,您可能需要指定要评估哪些类型的表达式。 - pfyod
显示剩余3条评论
6个回答

28

Javascript非常灵活。很少有情况需要使用eval(),并且在此处使用它肯定是不必要的。

如果您的ab变量是对象的一部分,则可以使用字符串下标访问它们:

myobj.a也可以被引用为myobj['a']

从那里,您可以使用变量作为下标,因此可以动态引用myobj中的任何元素--即:

var myobj = {a : 5, b : 10};

var dynamicProperty1 = 'a';
var dynamicProperty2 = 'b';

//gives 15.
alert( myobj[dynamicProperty1] + myobj[dynamicProperty2] );

无需使用 eval()。您可以按照自己的意愿构建 dynamicProperty 字符串,因此几乎具有无限的灵活性。

如果您的变量 ab 是全局变量,在浏览器中的 JS 全局变量实际上是 window 对象的子级,因此即使在使用全局变量时也可以使用此技术。

例如,您的全局变量 a 也可以通过 window.awindow ['a'] 访问,后者选项允许您执行上述相同的 dynamicProperty 技巧。

希望这能有所帮助。


5
您是想计算一个在接收方之前无法确定的方程吗?如果是,可以参考JavaScript中计算字符串值而不使用eval
简而言之,eval有时可用,但仅当方程式字符串来自可信来源时,并且需要类似于“评估动态方程”的东西。

2
也许使用 window['var' + num] 对你更有用。抱歉,我不太理解你的问题。

3
请不要使用窗口对象来存储变量。相反,请使用obj = Object.create(null); obj.a = "value1"; obj.b = " then two"; altert(obj.a + obj.b); // will alert "value1 then two"; - Jack G
1
除了 obj = ...var obj = ...window['obj'] = ... 完全相同之外。 - samb102

1
如果您可以将它们收集在一个对象下,例如root = {a: 1, b: 2},那么
Object.observe(root, function(newValues) { 
    res = newValues.object.a + newValues.object.b;
});

可以在ab更改时更新res变量。

0

看起来你正在尝试执行用户创建的动态方程。

例如,它可能是'a+b+c'或'dog+cat',而且你不知道。

处理这样的用户输入方程的最佳方法是将文本解析成标记,然后将标记转换为值/操作数。

这是很多工作,但有预先准备的解决方案。例如,math.js


0

这个问题另一个问题中,可以查看更多替代eval的方法,这两个问题可能被认为是重复的...

我知道这只是一个链接答案,但对于其他正在寻找替代eval的人来说,它肯定会有所帮助。


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