
JavaScript 为什么不要使用 eval
2016-08-21
展开全部
作者:王欣彤
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
不推荐使用eval的原因有很多,
1、eval 太神秘了,以至于很多人用错。所以不推荐使用。
这并不是eval 不好而是因为容易被用错。这并不是eval 不好而是因为容易被用错。
eval只是一个普通的函数,只不过他有一个快速通道通向编译器,可以将string变成可执行的代码。有类似功能的还有Function ,
setInterval 和 setTimeout。
2、 eval不容易调试。用chromeDev等调试工具无法打断点调试,所以麻烦的东西也是不推荐使用的…
3、说到性能问题,在旧的浏览器中如果你使用了eval,性能会下降10倍。在现代浏览器中有两种编译模式:fast path和slow path。fast path是编译那些稳定和可预测(stable and predictable)的代码。而明显的,eval不可预测,所以将会使用slow path ,所以会慢。
还有一个是,在使用类似于Closure Compiler等压缩(混淆)代码时,使用eval会报错。
(又慢又报错,我还推荐吗?)
4、关于安全性,我们经常听到eval是魔鬼,他会引起XSS攻击,实际上,如果我们对信息源有足够的把握时,eval并不会引起很大的安全问题。而且不光是eval,其他方式也可能引起安全问题。比如:
莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码…
所以啊,只要你的信息源不安全,你的代码就不安全。不单单是因为eval引起的。
你用eval的时候会在意XSS的问题,你越在意就越出问题,出的多了,eval就成噩梦了。
5、效率问题是程序逻辑问题。对于一些有执行字符串代码需求的程序中,不用eval而用其他方式模拟反而会带来更大的开销。
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
不推荐使用eval的原因有很多,
1、eval 太神秘了,以至于很多人用错。所以不推荐使用。
这并不是eval 不好而是因为容易被用错。这并不是eval 不好而是因为容易被用错。
eval只是一个普通的函数,只不过他有一个快速通道通向编译器,可以将string变成可执行的代码。有类似功能的还有Function ,
setInterval 和 setTimeout。
2、 eval不容易调试。用chromeDev等调试工具无法打断点调试,所以麻烦的东西也是不推荐使用的…
3、说到性能问题,在旧的浏览器中如果你使用了eval,性能会下降10倍。在现代浏览器中有两种编译模式:fast path和slow path。fast path是编译那些稳定和可预测(stable and predictable)的代码。而明显的,eval不可预测,所以将会使用slow path ,所以会慢。
还有一个是,在使用类似于Closure Compiler等压缩(混淆)代码时,使用eval会报错。
(又慢又报错,我还推荐吗?)
4、关于安全性,我们经常听到eval是魔鬼,他会引起XSS攻击,实际上,如果我们对信息源有足够的把握时,eval并不会引起很大的安全问题。而且不光是eval,其他方式也可能引起安全问题。比如:
莫名其妙给你注入一个<script src="">标签,或者一段来历不明的JSON-P请求,再或者就是Ajax请求中的eval代码…
所以啊,只要你的信息源不安全,你的代码就不安全。不单单是因为eval引起的。
你用eval的时候会在意XSS的问题,你越在意就越出问题,出的多了,eval就成噩梦了。
5、效率问题是程序逻辑问题。对于一些有执行字符串代码需求的程序中,不用eval而用其他方式模拟反而会带来更大的开销。
2018-06-27 · 百度知道合伙人官方认证企业
1【专注:Python+人工智能|Java大数据|HTML5培训】 2【免费提供名师直播课堂、公开课及视频教程】 3【地址:北京市昌平区三旗百汇物美大卖场2层,微信公众号:yuzhitc】
向TA提问
关注

展开全部
破坏代码可阅读性
eval(string)
参数
描述
string 必需。要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。
简单点就是说eval方法接收任何字符串,然后会编译和运行字符串,把它当成js代码来执行,到这里,我就发现一点不好的地方了。
如果我们要执行一段代码,一行一样写下来多好,为什么要把这些代码放到eval方法里来执行呢?
这无疑会破话代码的可阅读行,还有增加调试的难度。
eval伪装
有如下代码:
var foo = 1;
function test() {
var foo = 2;
eval('foo = 3');
return foo;
}
test(); // 3
foo; // 1
但是只有当eval被直接调用时才会按预期执行,否则eval将在全局作用域下执行。
var foo = 1;
function test() {
var foo = 2;
var bar = eval;
bar('foo = 3');
return foo;
}
test(); // 2
foo; // 3
所以,当对eval使用的位置不恰当是,会得到不同的结果,这样既混淆了结果,也不利于程序的执行,例如js的settimeout函数的第一个参数也接收字符串形式的方法,但是必须为全局定义的函数,内部定义的则不起作用。
function a(){
console.log(1);
}
function b(){
var a = function(){
console.log(3);
}
setTimeout('a();',1000);
}
b();//1
执行b方法打印出1而不是3则充分证明这一点。
安全性太差
由于eval方法接收任何字符串形式的参数,那么就会对安全性进行破坏,例如下面这段代码:
var c = $('input').val();
var obj = eval('({username:'+c+'})');
如果我在文本框输入alert(1)会得到什么结果呢?,可想而知,跟sql植入一个道理会破话安全性。
和JSON.parse比较
单纯比较:
var json_str = "{\"username\":\"dd\"}";
JSON.parse(json_str);//Object {username: "dd"}
eval('('+json_str+')'); //Object {username: "dd"}
看起来很正常,但是如果这样:
var json_str = "{\"username\":1+1}"
JSON.parse(json_str);//SyntaxError: Unexpected token +
eval('('+json_str+')');//Object {username: 2}
可以看出json.parse会首先检查语法是否正确,而eval则不会检查,无条件执行,这样话还是用json.parse好一些。
eval(string)
参数
描述
string 必需。要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。
简单点就是说eval方法接收任何字符串,然后会编译和运行字符串,把它当成js代码来执行,到这里,我就发现一点不好的地方了。
如果我们要执行一段代码,一行一样写下来多好,为什么要把这些代码放到eval方法里来执行呢?
这无疑会破话代码的可阅读行,还有增加调试的难度。
eval伪装
有如下代码:
var foo = 1;
function test() {
var foo = 2;
eval('foo = 3');
return foo;
}
test(); // 3
foo; // 1
但是只有当eval被直接调用时才会按预期执行,否则eval将在全局作用域下执行。
var foo = 1;
function test() {
var foo = 2;
var bar = eval;
bar('foo = 3');
return foo;
}
test(); // 2
foo; // 3
所以,当对eval使用的位置不恰当是,会得到不同的结果,这样既混淆了结果,也不利于程序的执行,例如js的settimeout函数的第一个参数也接收字符串形式的方法,但是必须为全局定义的函数,内部定义的则不起作用。
function a(){
console.log(1);
}
function b(){
var a = function(){
console.log(3);
}
setTimeout('a();',1000);
}
b();//1
执行b方法打印出1而不是3则充分证明这一点。
安全性太差
由于eval方法接收任何字符串形式的参数,那么就会对安全性进行破坏,例如下面这段代码:
var c = $('input').val();
var obj = eval('({username:'+c+'})');
如果我在文本框输入alert(1)会得到什么结果呢?,可想而知,跟sql植入一个道理会破话安全性。
和JSON.parse比较
单纯比较:
var json_str = "{\"username\":\"dd\"}";
JSON.parse(json_str);//Object {username: "dd"}
eval('('+json_str+')'); //Object {username: "dd"}
看起来很正常,但是如果这样:
var json_str = "{\"username\":1+1}"
JSON.parse(json_str);//SyntaxError: Unexpected token +
eval('('+json_str+')');//Object {username: 2}
可以看出json.parse会首先检查语法是否正确,而eval则不会检查,无条件执行,这样话还是用json.parse好一些。
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询