关于json数据在客户端使用程度比较频繁,与服务器交互使用json数据可以大大减少通讯数量,免除像xml那样携带大量的标签信息。在java开发领域,用来生成json格式字符串的jar包有官方的org.json.jar和sourceforge的那个json-lib,个人觉得官方的使用简明易懂,可以将bean和collection之类对象解析成json的数据格式字符串。在服务器解析生成json是相当简单的事情,其实在客户端解析并生成json对象也是相当容易的事情。
首先值得我们关注的是历史悠久的prototype.js框架,这个框架拓展了String的prototype,增加了evalJson方法可以方便地将json格式的字符串转化成json对象。像jQuery内部也封装了一个parseJSON方法,实现转化功能。出于性能和维护性的考虑,有些情况下我们想直接使用更为轻巧的代码转化json对象,出于浏览器的兼容性能方面考虑,可以使用官方的json.js框架。这里就提出了一个问题,为什么我们不能直接用javascript内置的函数来解析json格式字符串呢?从犀牛一书我们可以知道,定义一个对象,可以用大括号{}来定义并实例化生成一个新对象,而json正式利用这个特性来构造数据结构。而官方json的定义是
所以我们可以知道json返回数据基本格式是使用键值对形式,对此我们要知道关注的是在规范里面最为key的形式的string需要用双语号或单引号围绕起来。
从javascript的核心函数中我们知道有一个eval函数可以解析字符串形式的语句块,所以我们完全可以让eval来解析我们的json数据格式的字符串,因为我们的json就是利用对象字面值(Object Literals)来定义并实例化包含我们编写指定属性(类似键值对)的对象。所以我们完全可以直接将符合json格式的字符串作为参数传给eval,即可返回符合json规范的对象。但当我们解析的字符串是单个对象的的形式,即是是{x:1,y:2}这种形式的字符串,我们不能直接传递给eval解析。因为javascript内核函数eval解析这字符串时候,把这个字符串当做javascript语句块来解析,而恰巧x:和y:在javascript语言中符合label的定义格式。什么是label呢,就在再在个地方标记一下,然后可以给goto语句跳到标记label处运行。所以我们必须想办法来解决这个问题,不让javascript核心在解析这个语句时候将这个x:形式的字符串当做是一个label。(ps:李刚老师的疯狂java-突破程序员基本功的16课也提及到类似的问题,就是在java源码上写上http://www网址也正常编译)。
让我们比较两种解析代码:
- var jStr = "{x:1,y:2}";
- var v1 = eval(jStr); //解析错误
- var v2 = eval("("+jStr+")"); //解析正确
从上面代码我们可以了解到,单个对象形式要在包含对象定义的字串前后加小括号包围起来(数组的json对象则没问题[{x:1,y:2},{x:1,y:2}]),才能正确解析。所以小括号是解决问题的关键,我们有必要了解一下小括号在javascript里面的作用。
小括号有下面五种用法:
- 函数声明时参数表:
function
func(arg1,arg2){.....}
- 和一些语句联合使用以达到某些限定作用(语句结构):
for
(
var
a
in
obj){.....
} - 和new一起使用用来传值(实参):
var
p1 =
new
Person(
'Jack'
,26);
- 作为函数或对象方法的调用运算符(如果定义了参数也可与语义3一样传实参):
func();
obj.func();
- 强制表达式运算 起到强制()内部内容必须解析成表达式,这就是我们的用eval来进行json字串解释的关键所在。