javascript eval() 方法在过滤时降低了性能

标签 javascript performance eval

我正在从过滤器数组创建一个 where 子句字符串。

var where_clause_string = "(((true && ['SACRAMENTO','CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1) || (false && [].indexOf(raw_data[i]['city']) === -1)) || false)";
var raw_data_length = raw_data.length
  , filtered_data = [];
for(var i = 0; i < raw_data_length; i++) {
  if (eval(where_clause_string)) {
    filtered_data.push(raw_data[i]);
  }
}

然后,我遍历作为对象数组的数据,并只返回通过真值测试的那个对象。

它给出了预期的结果,但性能却一塌糊涂。仅过滤 1500 行需要约 2-3 秒。如果在不使用 eval() 的情况下对条件进行硬编码,则该过程非常快。

实现这一目标的替代方法是什么?

最佳答案

另一种方法是构建一个函数:

var where_clause_string = "(((true && ['SACRAMENTO','CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1) || (false && [].indexOf(raw_data[i]['city']) === -1)) || false)";

var evaler = new Function('raw_data', 'i', "return "+where_clause_string);

var raw_data_length = raw_data.length
  , filtered_data = [];
for(var i = 0; i < raw_data_length; i++) {
  if (evaler(raw_data, i)) {
    filtered_data.push(raw_data[i]);
  }
}

如果你想更进一步,你可以使用Array.prototypefilter 函数。它还将确保函数生成不是去优化的可能原因(参见 Optimization Killers):

var where_clause_string = "(((true && ['SACRAMENTO','CITRUS HEIGHTS'].indexOf(raw_data[i]['city']) > -1) || (false && [].indexOf(raw_data[i]['city']) === -1)) || false)";

var filtered_data = raw_data.filter(new Function(
    'v', "return "+where_clause_string.replace(/raw_data\[i\]/g,'v')
));

但通常最好从结构化数据开始,而不是要评估的原始字符串。使用我建议的函数可以获得更好的性能,但您仍然会遇到字符串代码的维护、可读性和安全性问题。也许它可能是这样的

var criterium = {
    ok_cities:['SACRAMENTO','CITRUS HEIGHTS'],
    nok_cities:[]
};

关于javascript eval() 方法在过滤时降低了性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29766991/

相关文章:

javascript - 基本的 JavaScript 问题

javascript - 关闭后 qtip2 位置发生变化

Python:将逗号分隔的字符串直接拆分为一个集合

c - 用c计算欧氏距离的最快方法

javascript - AngularJS 过滤多个参数

javascript - 油猴:喜欢还是讨厌?

c++ - 局部变量初始化应该是强制性的吗?

php - 我可以在 eval() 中执行 mysql_query 吗?

javascript - 不使用 eval 向 JSON 添加函数

javascript - 如何在js中简单地使用带有Abs()的eval字符串公式(谷歌应用程序脚本)