欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js中的eval函数

程序员文章站 2024-03-21 08:24:28
...

晓得eval函数对于程序优化不友好,所有也从来没有打算用它,但是昨天写简单爬虫的时候却不得不用它。 由于只是简单爬个东西,也没有用phantomjs,也没有用代理,所有次数多了,网站没有直接返回内容而是返回一个重定向--带有window.location= "id=" + "" + "" + ...的空html,就不好处理了。

eval函数

javascript中的eval函数可以接受一个字符串为参数,并将其中的内容是做好像在书写时就存在程序中这个位置一样,从而可以在代码中用程序生成代码并执行,就像本来就写在那里一样。

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)

作用域

非严格模式

根据上面所属,可以看出,eval函数的作用域就是函数所处的作用或者说该函数调用的作用域。所以由于那段代码中声明了一个新的变量,因此会对foo即eval所处的词法作用域进行修改

严格模式下

如果将上面的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函数中获取最终的location

let query = $("script").text().replace("window.location=", "")
let newAdds = "http://www.xxx.com" + eval(`${query}`)

注意:这里用到eval的返回值,同时由于用到的是es6的模块,默认整个模块都是严格模式,所有eval不会对所在的词法作用域进行修改。尽管严格模式对eval进行了限制,但是还是尽量少的使用,我也是没得办法了撒。

转载于:https://my.oschina.net/u/1249401/blog/821253