json字符串解析

总结(1.eval   2. new Function  3.$.getJSON)

 

1.eval  
var dataObj=eval("("+data+")");//转换为json对象


e为什么要 eval这里要添加 “("("+data+")");//”呢?

原因在于:eval本身的问题。 由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当

成一个语句块来处理,所以必须强制性的将它转换成一种表达式。

加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式

(expression)转化为对象,而不是作为语 句(statement)来执行。举一个例子,例如对象字

面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始 和结束标记

,那么{}将会被认为是执行了一句空语句。所以下面两个执行结果是不同的:
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]

(补充 关于eval中加()的原因)

首先不存在强制运算符这个说法.
这里应该仅是 分组运算符. 作用是优先级. 本质就是舍弃其他可能的多余的语法树.

第5条,之所以要这样做的原因是 {} 花括号二义性造成的.
eval('{a:1}')//不会抛出异常.
eval('{a:1,b:2}')//抛出异常
这并不是eval的错. 错误来自语法分析时, {}被当做 statement block,而不是一个 JSONObject.
所以.抛出异常是因为a:1被解析成lableStatement 了.那么它后面的 "," 逗号,就使得parser不得不停下来了.因为 逗号运算符不能出现在lableStatement后面.

所以
{
a:1,
b:2
}
在任何被解析为statement block的情况下.都将导致异常.
解决办法.把他们并入表达式.让parser使用 JSONObject的语法树.比如
({a:1,b:2})
1,{a:1,b:2}
+{a:1,b:2}
var a ={a:1,b:2}
等等等等...

说说为什么()不是强制运算符,因为它不具备这个功能.
分组运算符 同 delete typeof 等运算符类似. 不会对运算元.造成 GetValue() .

举个例子:

delete 玩笑; //不会抛出异常.

原因是运行时,执行到 delete 玩笑; 时, 并不会对标识符-玩笑,进行GetValue().

delete (玩笑);//同样不会抛出异常.

可见分组运算符() 并没有对 标识符 -玩笑 做额外的工作. 它仅仅是影响语法树的产生过程.

从ECMA262的角度来看此问题亦如此. 这里涉及到 Reference Type 的base property 为null时的情况下,对其 GetValue()才抛出异常.


2.$.getJSON

对于服务器返回的JSON字符串,如果jquery异步请求将type(一般为这个配置属性)设

为“json”,或者利 用$.getJSON()方法获得服务器返回,那么就不需要eval()方法了,因为

这时候得到的结果已经是json对象了,只需直接调用该对象即可,这 里以$.getJSON方法为例说

明数据处理方法:
$.getJSON("http://www.phpzixue.cn/",{param:"gaoyusi"},function(data){
//此处返回的data已经是json对象
//以下其他操作同第一种情况
$.each(data.root,function(idx,item){
if(idx==0){
return true;//同countinue,返回false同break
}
alert("name:"+item.name+",value:"+item.value);
});
});
这里特别需要注意的是方式1中的eval()方法是动态执行其中字符串(可能是js脚本)的,这样很

容易会造成系统的安全问题。所以可以采用一些规避了eval()的第三方客户端脚本库,比如JSON

in JavaScript就提供了一个不超过3k的脚本库。


3.new Function
第二种解析方式就是使用Function对象来完成,它的典型应用就是在JQUERY中的AJAX方法下的

success等对于返回数据data的解析

var json='{"name":"CJ","age":18}';

data =(new Function("","return "+json))();

 

此时的data就是一个会解析成一个 json对象了

 

 

网上有例:

<script type="text/javascript">     
        //var aa="{aa:'xx'}";  
       var aa="{name:'cola',item:[{age:11},{age:22},{age:23},{age:23}]}";  
        var now=new Date().getTime();  
        for(var i=0;i<1000;i++){  
           eval("("+aa+")");   
            }  
        var now1=new Date().getTime();  
         alert(now1-now+" eval");  
              
        var now2=new Date().getTime();  
        for(var i=0;i<1000;i++){  
            var fn=new Function("return"+aa);  
            fn();             
            }  
        var now3=new Date().getTime();  
         alert(now3-now2+" new Function");  
       </script> 

总结:

在ie下两种方法时间差不多

在ff下,网上提到用ff2下 用new Function比eval快很多,但是自己的ff浏览器为24.0,反而是eval运行的时间更快。。。

(文章参考了:http://jljlpch.iteye.com/blog/240545  以及  http://www.cnblogs.com/fishtreeyu/archive/2011/11/05/2237190.html  多谢分享学习中)

posted @ 2013-11-21 15:26  L_woniu  阅读(294)  评论(0编辑  收藏  举报