曉得eval函數對於程序優化不友好,全部也歷來沒有打算用它,可是昨天寫簡單爬蟲的時候卻不得不用它。 因爲只是簡單爬個東西,也沒有用phantomjs,也沒有用代理,全部次數多了,網站沒有直接返回內容而是返回一個重定向--帶有window.location= "id=" + "" + "" + ...
的空html,就很差處理了。javascript
javascript中的eval函數能夠接受一個字符串爲參數,並將其中的內容是作好像在書寫時就存在程序中這個位置同樣,從而能夠在代碼中用程序生成代碼並執行,就像原本就寫在那裏同樣。html
function foo(str, a) { console.log(eval(str)) console.log(a, b) } var b = 2; foo("var b = 3", 1) //1,3 console.log(b)
非嚴格模式java
根據上面所屬,能夠看出,eval函數的做用域就是函數所處的做用或者說該函數調用的做用域。因此因爲那段代碼中聲明瞭一個新的變量,所以會對foo即eval所處的詞法做用域進行修改。es6
嚴格模式下函數
若是將上面的foo函數聲明爲嚴格模式:性能
"use strict" function foo(str, a) { console.log(eval(str)) console.log(a, b) //referenceerror: b is not defined } var b = 2; foo("var b = 3", 1) //1,3 console.log(b)
在嚴格模式下,eval在運行是有其本身的詞法做用域,所以不會對其位於的詞法做用域進行修改。優化
javascript引擎會在編譯階段進行數項性能的優化,其中有些優化依賴於代碼詞法的靜態分析,並預先肯定全部變量和函數的位置,才能在執行過程當中快速找到標識符。因爲eval能夠隨意修改詞法做用域,因爲它內部字符串是動態的也沒法在詞法分析階段知道到底會是什麼代碼,因此會帶引擎的優化帶來擾亂,最壞狀況下,全部的優化都是無心義的,由於可能帶來後果是引擎不會作任何優化,從而致使在大量使用eval的程序中運行很是緩慢。網站
在大量請求後會接受到帶有下面js的空html代理
window.location="/html/" +"gndy/d" + "yzz/i"+ "ndex_" + "154.html"+"?__w"+ "ang" + "an=3" + "4e" + "fe0198" + "473" +"d1c"+ "60f11540"+"e216"+ "17c7741"+ "48393245" + "0_4" + "3"+"8180";
簡單的作法就是丟到eval函數中獲取最終的locationcode
let query = $("script").text().replace("window.location=", "") let newAdds = "http://www.xxx.com" + eval(`${query}`)
注意:這裏用到eval的返回值,同時因爲用到的是es6的模塊,默認整個模塊都是嚴格模式,全部eval不會對所在的詞法做用域進行修改。儘管嚴格模式對eval進行了限制,可是仍是儘可能少的使用,我也是沒得辦法了撒。