eval,一個我曾經避之不及的函數,最近我對它產生了一點新的感觸:eval有時候也可以用,有奇效。 一般在使用js進行開發時,是不建議使用eval這類函數的。在JavaScript中,eval可以計算傳入的字元串,將其當作js代碼來執行。因為它可執行js代碼的特性,有可能被第三方利用,傳入惡意js代 ...
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有了新的認識。
我的個人博客地址:http://www.cnblogs.com/xsilence/本文來自博客園,作者:silencetea,轉載請註明原文鏈接:https://www.cnblogs.com/xsilence/p/17252805.html