JavaScript危险函数|eval()函数

  • Post author:
  • Post category:java


描述

eval()是全局对象的一个函数属性

eval()的参数是一个字符串,如果字符串表示的是表达式,eval()会对表达式进行求值,如果参数表示一个或多个JavaScript语句,那么eval()就会执行这些语句,不需要用eval()来执行一个算术表达式:因为javascript可以自动为算术表达式求值

如果你以字符串的形式构造了算术表达式,那么可以在后面用eval()对他求值,例如,假设你有一个变量x,你可以通过将表达式的字符串值(例如3*x+2)赋值给一个变量,然后在你的代码后面的其他地方调用eval(),来推迟涉及x的表达式的求值

如果eval()的参数不是字符串,eval()会将参数原封不动地返回,在下面例子中,String构造器被指定,而eval()返回了String对象而不是执行字符串

eval()的用法

eval()函数可以用来计算某个字符串,并执行其中的javascript带啊吗,其语法eval(string);

如果传入的参数不是字符串,则直接返回这个参数

eval()函数会将传入的字符串当作javascript代码进行执行

console.log(eval('17+9'));
//输出26
console.log(eval(new String('23+26')));
//输出expected 23+26
console.log(eval('17+9') == eval('26'));
//输出true
console.log(eval(new String('23+26')) == eval('23+26'));
//输出false


输出结果

参数

eval(string)

一个表示Javascript表达式,语句或一系列语句的字符串,表达式可以包含变量与已存在对象的属性

返回值

返回字符串中代码的返回值,如果返回值为空,则返回undefined

如果eval()的参数不是字符串,eval()会将参数原封不动地返回,在下面例子中,string构造器被指定,而eval()返回了string对象而不是执行字符串

eval(new String("17+9"));
//返回了包含"17+9"的字符串对象
eval("63+23");
//returns 86

你可以使用一些通用的方法来绕过这个限制,例如使用toString()

var experssion = new String("63+23");
eval(experssion.toString());
//最终输出的就是63+23

如果你间接的使用eval(),比如通过一个引用来调用它,而不是直接的调用eval,从ECMAScript 5起,它工作在全局作用域下,而不是局部作用域中,这就意味着,例如,下面的代码的作用声明创建一个全局函数,并且eval中的这些代码在执行期间不能在被调用的作用域中访问局部变量

function test(){
    var D = 17 , L = 15;
    console.log(eval('D + L'));
    //直接调用,使用本地作用域,结果是32
    var djxlyq = eval;
    //等价于在全局作用域调用
    console.log(djxlyq('D + L'));
    //间接调用,使用全局作用域,throws ReferenceError 因为'D'未定义
    (0,eval)('D + L');
    //另一个间接调用的例子
}

带有eval的危险函数格式

function looseJsonParse(djxlyq){
    return eval("(" + djxlyq + ")");
}
console.log(looseJsonParse(
    "{a:(63-23) , b:function(){} , c:new Date()}"))


代替eval的代码

function looseJsonParse(djxlyq){
    return Function('"use strict";return(' + djxlyq + ')')();
}
console.log(looseJsonParse(
    "{a:(17-15), b:function(){}, c:new Date()}"
))

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

eval危险性

eval函数可能有许多小的问题,总的来说有两个大问题 性能慢合代码植入

性能–运行eval函数需要运行解释器/编译器,如果你的代码是编译的,那么这也是个大问题,因为你需要调用一个很重的编译器,但是JavaScript是一门解释性语言,这意味着在一般的情况下eval函数并不可能有很大的性能影响,js在解析期间也是需要调用,解释器或编译器,而不是需要再单独的调用另一个解释器或编译器,这种情况下eval函数并没有浪费很多时间

代码注入问题 eval可能在权限提升的情况下运行一些代码,比如在管理员或者root权限下运行像”whoami rm等命令指令”但是在浏览器中的js没有这个问题,因为程序无论如何都是再用自己的账户中运行类似于php exec

toString()

toString()方法可把一个Number对象转换为一个字符串,并返回结果

NumberObject.toString(radix)

radix:可选,规定表示数字的基数,使2~36之间的整数,若省略该参数,则使用基数10,但是要注意,如果该参数是10以外的其他值,则ECMAScript标准允许实现返回任意值

toString()返回值

数字的字符串表示,例如,当radix为2时,NumberObject会被转换为二进制值表示的字符串

toString()实例

在本例中,将把一个数字转换为字符串:

<script type="text/javascript">
    var number = new Number(63);
    document.write(number.toString())
</script>
//输出值将是63但是类型是字符串类型

toString可以将int类型字符串转换为string字符串



版权声明:本文为qq_60115503原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。