eval 的使用与延展

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了eval 的使用与延展相关的知识,希望对你有一定的参考价值。

前些日子用到了eval()处理json数据,习惯于每次添加‘(‘+json+‘)‘处理数据,也没去深究为什么这么做,刚好同事问我这个问题,瞬间哑口无言,只会如何操作,却讲不出原因,这不符合咱程序员严谨的工作态度,仔细思考了一会,简略的谈谈吧。

可能会随时脑洞,望各位见谅。

  1.什么是json?

  JSON(javascript Object Notation) 是一种轻量级的数据交换格式,是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度。

  • JSON就是一串字符串 只不过元素会使用特定的符号标注,其书写格式是:名称/值对。
    {"name":"json"} 
  • {} 双括号表示对象
  • [] 中括号表示数组
  • "" 双引号内是属性或值      

    现在还有很多人存在一些误区,为什么{name:‘json‘}在检验时通过不了,

  那是因为JSON官网最新规范规定

  如果是字符串,那不管是键或值最好都用双引号引起来,所以上面的代码就是 {"name":"json"}

  不要反驳,官网就是这么定义的。

  • : 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象);  

  2. 如何解析json?

  如果从后台接收json数据时,jquery将type设为‘json‘,或者利用$.getJSON()获取,此时接收到的json是对象格式,不需要特殊处理,可直接使用;

  但是如果接收的json格式是字符串类型,这时就需要将其转换成对象格式了,两种方法:eval() 和 new Function();

  1. eval

  var json=‘{"name":"lee","age":"15"}‘
  str=window.eval(‘(‘+ json+‘)‘);

 

结果如图:技术分享

我们可以看出解析后的json数据格式为对象,方便我们的后续操作处理,但是,我们为什么要用‘(‘+json+‘)‘这样的处理呢?

个人拙见如下:首先eval 可将字符串解析为

    • 具体的对象
    • 求表达式的值
    • 执行语句
    • 求值
    • 处理日期数据

还记得json的格式吗?以"{"开头对吧,在此那么你还记的语句块的格式吗?也是以"{"开头是吧,那么问题就来了,eval解析时会把我们的json当成语句块,而且这个所谓的语句块里还有":",那么极有可能会报错,如图:

技术分享

在此随便扯一点别的知识点。。

表达式与语句

表达式:表达式,是由数字、算符、数字分组符号(括号)、自由变量和约束变量等以能求得数值的有意义排列方法所得的组合。约束变量在表达式中已被指定数值,而自由变量则可以在表达式之外另行指定数值。

语句:JavaScript 语句向浏览器发出的命令。语句的作用是告诉浏览器该做什么。通常我们在每条可执行的语句结尾添加分号以分隔 JavaScript 语句,多条语句构成语句块。

有些时候,表达式和语句会看不出区别,但其作用做不同,即有一些表达式会出现在语句的上下文中,为了解决歧义,JavaScript语法禁止表达式以大括号"{"或关键字"function"开头,如果要以"{"开头的表达式能被正确解析,需要把这个"{}"包裹的内容放在"()"中,确保表达式被解析在表达式上下文中,如果表达式被解析在表达式上下文中,此时json解析后会转换成对象类型,这就是我们想要的结果。

表达式与语句的交集:

            技术分享

好了,原理讲解完成,那么各位应该明白以‘(‘+json+‘)‘格式处理eval接收数据的原理了吧,如果实在不明白,那就偷个懒,每次都不加‘(‘+json+‘)‘,报错了再加上,时间长了也就能明白了(千万别听我的,我开玩笑的%>_<%)。

但是,but,各位有没有听过前辈们讲过一段话:

对于eval,要理解它,远离它。

为什么呢?

为什么执行会缓慢呢? 这就要引出另一位主角了:new  Function();

2.new Function

  先扯些别的,定义函数有三种方式,分别为

  • 函数声明  function fn( arg ) {}
  • 函数表达式 var fn=function( arg ) {};
  • new     var fn=new Function(arg1,arg2...argn,body);   ps:此处的arg参数必须是字符串形式,body为函数体,同样为字符串形式

来看代码:

//1.取最大值
var getMax=new Function(‘Math.max(arguments)‘);
var max=getMax(1,4,5);
//2.处理json数据
var json=‘{"name":"json","age":"18"}‘;
data=(new Function(‘‘,‘return‘+json))();
console.log(data);

 

 结果如图:  

 技术分享

我们再来看看所谓的代码执行缓慢的问题是什么,直接上代码解释:

// 1.eval
    function evalFun (){
        var start= (new Date).getTime();
        var func=eval(‘(function(a,b,c,d,e,f,g){return a*b*c*d*e*f*g;})‘);
        var result= func(4234,3424,4234,4324,423,34234,53453);
        console.log(result);
        var time=  (new Date).getTime()-start;
        return time;
    }

//  2.new Function
    function newFun (){
        var start= (new Date).getTime();
        var func=new Function([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘,‘g‘],‘return a*b*c*d*e*f*g;‘);
        var result=func(4234,3424,4234,4324,423,34234,53453);
        console.log(result);
        var time=  (new Date).getTime()-start;
        return time;
}
    t1=evalFun();//输出处理时间差,单位ms
    t2=newFun();
    console.log(时间比(new Function/eval):‘+ t2/t1);    //两者时间对比

 

两种方法所处理数据相同,结果相同,请看时间比:

技术分享

结果清晰明了,差别很大是吧,各位看官,您看懂了吧。

最后:鄙人才疏学浅,在此献丑了,望各位前辈批评指正,在此感谢!------(未完待续)                                      2016-04-05

 

        

 

 

 

以上是关于eval 的使用与延展的主要内容,如果未能解决你的问题,请参考以下文章

面向接口编程详解——编程实例

面向接口编程详解——编程实例

第二天,php笔记,菜鸟级别,新手望见谅!

[转]神经网络-激活函数

jQuery源码逐行分析学习01(jQuery的框架结构简化)

新手关于log4j.properties的问题,望各位大大相助.