7

eval有时候也可以用,而且有奇效 - silencetea

 1 year ago
source link: https://www.cnblogs.com/xsilence/p/17252805.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

eval有时候也可以用,而且有奇效

eval,一个我曾经避之不及的函数,最近我对它产生了一点新的感触:eval有时候也可以用,有奇效。

一般在使用js进行开发时,是不建议使用eval这类函数的。在JavaScript中,eval可以计算传入的字符串,将其当作js代码来执行。因为它可执行js代码的特性,有可能被第三方利用,传入恶意js代码执行,因此这个函数存在安全风险。再加上eval执行的速度低于普通的js程序,因此在日常开发中,它的使用准则是“能不用就不用”、“代码中使用eval是很丑陋的一件事”。

但是这次在做拉线功能时,我“不得不”使用了它。

拉线由于数据量小,可以通过矢量渲染的方式渲染到地图上,但是通过geoserver获取的坐标数据和样式数据是分离的,且没有样式名能将二者关联起来。
样式数据里面规定每组筛选条件对应一组样式值(线段的颜色、宽度,面的颜色、透明度),以以下这段样式数据为例:

{
  "Description": {
      "Title": "hidetitle"
  },
  "Filter": {
      "And": {
          "PropertyIsGreaterThanOrEqualTo": {
              "PropertyName": "rsrp_rate",
              "Literal": "0"
          },
          "Not": {
              "PropertyIsNull": {
                  "PropertyName": "eci"
              }
          },
          "PropertyIsEqualTo": {
              "PropertyName": "geo_type",
              "Literal": "cell"
          },
          "PropertyIsLessThanOrEqualTo": {
              "PropertyName": "rk",
              "Literal": "3"
          },
          "PropertyIsLessThan": {
              "PropertyName": "rsrp_rate",
              "Literal": "0"
          }
      }
  },
  "PolygonSymbolizer": {
      "Fill": {
          "SvgParameter": [
              "#f56e3f",
              "0.15"
          ]
      },
      "Stroke": {
          "SvgParameter": [
              "#f56e3f",
              "4"
          ]
      }
  },
  "Name": "cell1-3 and rate 0-20"
},

它的涵义是:
当满足(rsrp_rate >= 0 && ect !== null && geo_type === 'cell' && rk <= 3 && rsrp_rate < 0) 的条件时,面填充颜色使用#f56e3f、透明度为0.15,线段颜色使用#f56e3f、宽度为4。

如果使用常规方式去进行拉线数据值和样式数据的计算匹配,无疑会很繁琐,执行筛选所需要的时间也会很长,这种结果无疑是“丑陋”的。但是如果使用eval,就会有奇效。

我可以先将样式数据进行处理成类似

{ operator: '>=', name: 'rsrp_rate', value: 0 }

这样的结构,并存入数组,这个数组里存放的都是and关系的筛选条件。

然后从拉线数据里获取每个指标的值indexValue,进行如下拼装:

let dataItem = { operator: '>=', name: 'rsrp_rate', value: 0 };
let filterValue = dataItem.value;
let indexValue = lineData[dataItem.name]; // 此处lineData中存储着单个拉线的指标值
eval('filterValue' + dataItem.operator + 'indexValue') ;
// 上方这行代码在编译后执行的是: filterValue >= indexValue

利用eval可以将传入的字符串当作js语句执行的特性,我就可以得到一个条件判断结果,代码相对而言也简洁很多,使用eval,反尔让代码变得优雅,大大提高了数据匹配的效率和代码的可维护性。

总之,这段开发经历,让我对eval有了新的认识。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK