java script eval_eval()

eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。

eval() 通常比其他替代方法更慢,因为它必须调用 JS 解释器,而许多其他结构则可被现代 JS 引擎进行优化。

此外,现代JavaScript解释器将javascript转换为机器代码。 这意味着任何变量命名的概念都会被删除。 因此,任意一个eval的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值。 另外,新内容将会通过 eval() 引进给变量, 比如更改该变量的类型,因此会强制浏览器重新执行所有已经生成的机器代码以进行补偿。 但是,(谢天谢地)存在一个非常好的eval替代方法:只需使用 window.Function。 这有个例子方便你了解如何将eval()的使用转变为Function()。

使用eval的糟糕代码:

function looseJsonParse(obj){

return eval("(" + obj + ")");

}

console.log(looseJsonParse(

"{a:(4-1), b:function(){}, c:new Date()}"

))

不用eval的更好的代码:

function looseJsonParse(obj){

return Function('"use strict";return (' + obj + ')')();

}

console.log(looseJsonParse(

"{a:(4-1), b:function(){}, c:new Date()}"

))

比较上面的两个代码片段,两个代码片段似乎是以相同的方式工作,但再想一想:eval的这个代码的速度要慢得多。 注意c: new Date()在执行体中。 在没有eval的函数中,对象在全局范围内被用来进行计算,因此浏览器可以放心的假设Date是来自window.Date的而不是一个名为Date的局部变量。 然而,在使用eval()的代码中,浏览器不能假设这一点,因为如果您的代码是下面这个:

function Date(n){

return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0];

}

function looseJsonParse(obj){

return eval("(" + obj + ")");

}

console.log(looseJsonParse(

"{a:(4-1), b:function(){}, c:new Date()}"

))

因此,在eval()版本的代码中,浏览器被迫进行高代价的查找调用以检查是否存在名为Date()的任何局部变量。 与Function()相比,这是非常低效的。

在类似的情况下,如果您确实希望能够从Function()内部的代码调用Date函数,该怎么办? 你应该躲避并退回到eval()吗? 绝对不是,永远不要这么做。 而是尝试下面的方法。

function Date(n){

return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0];

}

function runCodeWithDateFunction(obj){

return Function('"use strict";return (' + obj + ')')()(

Date

);

}

console.log(runCodeWithDateFunction(

"function(Date){ return Date(5) }"

))

由于三重嵌套函数,上面的代码似乎效率低下,但让我们分析一下上述有效方法的好处:

1.它使得传递给runCodeWithDateFunction的字符串中的代码更少。

2.函数调用开销很小,使得代码尺寸小得多,值得获益

3. Function()更容易让你的代码利用特性修饰"use strict";

4.代码不使用eval(),使其比其他方式快几个数量级。

最后,我们来看看简化版。 使用如上所示的Function(),您可以更有效地缩小传递给runCodeWithDateFunction的代码字符串,因为函数参数名称也可以缩小,如下面的缩小代码所示。

console.log(Function('"use strict";return(function(a){return a(5)})')()(function(a){

return"Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" ")[a%7||0]}));

对于常见用例,eval()或Function()还有更安全(而且更快!)的替代方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值