您的位置:首页 > Web前端 > JavaScript

JavaScript:JSON详解

2016-06-06 21:34 495 查看
向服务器发出Ajax请求时,可以以两种不同的方式从服务器响应检索数据:一种是使用XMLHttpRequest对象的reponseXML属性访问XML格式的数据;一种是XMLHttpRequest对象的responseText属性访问字符串格式的数据。当前,XML是进行数据传输的标准语言,但是使用XML的缺点之一是很难对它进行解析并提取要添加到页面的数据。

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,我们称之为JavaScript对象表示法。使用JSON进行数据传输的优势之一是JSON实际上就是JavaScript。它基于ECMAScript第3版中JavaScript对象字面量语法子集的一种文本格式。这表示可以使用responseText从服务器中检索JSON数据,然后再使用JavaScript的eval()方法将JSON字符串转换成JavaScript对象,那么,使用附加JavaScript就可以很地从该对象中提取数据,而不需要处理DOM。

另外,也有针对大部分编程语言(包括C++,C#,ColdFusion、Java、Perl、PHP和Python)的JSON库,这些库能将上述语言格式化数据转换成JSON格式。

关于JSON,最重要的是要理解它是一种数据格式,不是一种编程语言。虽然具有相同的语法形式,但JSON并不从属于JavaScript。而且,并不是只有JavaScript才使用JSON,毕竟JSON只是一种数据格式。

尽管有许多宣传关于XML如何拥有跨平台,跨语言的优势,然而,除非应用于Web Services,否则,在普通的Web应用中,开发都经常为XML的解析作秀了脑筋,无论是服务器端生成或处理XML,还是客户端用JavaScript解析XML,都常常导致复杂的代码,极低的开发效率。实际上,对于大多数Web应用来说,根本不需要要复杂的XML来传输数据,XML的扩展性很少具有优势,许多Ajax应用甚至直接返回HTML片段来构建动态Web页面。和返回XML并解析它相比,返回HTML片段大大降低了系统的复杂性,但同时缺少了一定的灵活性。XML使用元素、属性、实体和其他结构。JSON不是文档格式,因此它不需要这些附加结构。因为JSON数据只包括“名-值”对(对象)或值(数组),所以JSON数据比同等的XML数据占用更少的空间,执行速度更快。

一、JSON语法

JSON的语法可以表示以下三种类型的值:

简单值:使用与JavaScript相同的语法,可以再JSON中表示字符串、数值、布尔值和null,但是JSON不支持JavaScript中的特殊值undefined。

对象:对象作为一种复杂数据类型,表示的是一组无序的键值对儿。而每个键值对儿中的值可以是简单值,也可以是复杂数据类型的值。

数组:数组也是一种复杂数据类型,表示一组有序的值得列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型—简单值、对象或数组。

1、简单值

JSON数据结构包含以下简单值类型:字符、数字、布尔值(true/false)、null。

JSON字符串必须使用双引号括起来。它们使用标准的JavaScript转义序列。因此在以下列字符的前面要添加一个反斜线。

2、对象

{

"name":"zzmm",

"age":29,

"school":{

"name":"zzzxxx",

"location":"hunan"

}

}

JSON对象需要注意几点:

(1)、没有声明变量,JSON中没有变量的概念。

(2)、没有末尾的分号,因为它不是JavaScript语句。

(3)、对象的属性名必须加双引号,单引号会导致语法错误。

(4)、同一个对象中绝对不允许出现两个相同的属性名。

3、数组

在JSON中,可以采用JavaScript中的数组字面量的语法表示一个数组:

[25,"hi",true]

同样要注意,JSON数组也没有变量和分号,把数组和对象结合起来,可以构成更加复杂的数据集合,例如:

[

{ "firstName":"John" , "lastName":"Doe" },

{ "firstName":"Anna" , "lastName":"Smith" },

{ "firstName":"Peter" , "lastName":"Jones" }

]

二、解析和序列化

JSON之所以流行是因为可以把JSON数据结构解析为有用的JavaScript对象。例如取得上面例子中的第三个人的firstName。JSON数据在解析为JavaScript对象之后,只要一行简单的代码可以取得第三个人的firstName。

peoples[2].firstName;

在DOM结构中查找数据的代码:

document.getElementsByTagName(“people”)[2].getAttribute(“firstName”);

1、JSON对象

早期的JSON解析器基本上就是使用JavaScript的eval()函数,但是由于使用eval()对JSON数据结构求值存在风险,因为可能会执行一些恶意代码,所以ECMAscript5对解析JSON的行为进行了规范,定义了全局对象JSON。

JSON对象有两个方法:stringify()和parse()。在最简单的情况下,这两个方法分别用于把JavaScript对象序列化为JSON字符串和JSON字符串解析为原生JavaScript值。

var people={
"name":"zzmm",
"age":29,
"school":{
"name":"zzzxxx",
"location":"hunan"
}
};
//把JavaScript对象序列化为一个JSON字符串
var jsonText=JSON.stringify(people);
alert(jsonText);//{"name":"zzmm","age":29,"school":{"name":"zzzxxx","location":"hunan"}}
//JSON字符串解析为原生JavaScript值
var peopleCopy=JSON.parse(jsonText);
alert(peopleCopy);//[object,Object]


2、序列化选项

JSON.stringify()还可以接收另外两个参数,第一个参数是个过滤器,可以是一个数组,也可以是一个函数;第二个参数是一个选项,表示是否在JSON字符串中保留缩进。

(1)、过滤结果

过滤器参数是数组,那么JSON.stringify()的结果中将只包含数组中列出的属性。例如:

var people={
"name":"zzmm",
"age":29,
"school":{
"name":"zzzxxx",
"location":"hunan"
}
};
//JSON.stringify()第二个参数是数组。
var jsonText=JSON.stringify(people,["name","age"]);
alert(jsonText);//{"name":"zzmm","age":29}


如果第二个参数是函数,传入的函数接收两个参数,属性(键)名和属性值。根据属性(键)名可以知道应该如何处理要序列化的对象中的属性。属性名只能是字符串,而值并非键值对儿结构的值时,键名可以使空字符串。注意如果函数返回了undefined,那么相应的属性会被忽略。例如:

var people={
"name":"zzmm",
"age":29,
"year":2016,
"school":[
"zzzxxx",
"hunan"
],
"edition":3
};
//JSON.stringify()第二个参数是函数。
var jsonText=JSON.stringify(people,function(key,value){
switch(key){
case "name":
return "zm";
case "age":
return "18";
case "year":
return undefined;
case "school":
return value.join(",");
default:
return value;
}
});
console.log(jsonText);
alert(jsonText);//{"name":"zm","age":"18","school":"zzzxxx,hunan","edition":3}


(2)、字符串缩进

JSON.stringify()第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的是每个级别缩进的空格数,最大缩进空格数为10,大于10的值都会自动转换为10。例如

var people={
"name":"zzmm",
"age":29,
"year":2016,
"school":[
"zzzxxx",
"hunan"
],
"edition":3
};
//JSON.stringify()第三个参数是数值。
var jsonText=JSON.stringify(people,null,4);


保存在jsonText中的字符串如下所示:

{

"name": "zzmm",

"age": 29,

"year": 2016,

"school": [

"zzzxxx",

"hunan"

],

"edition": 3

}

如果缩进参数是一个字符串而非数值,则这个字符串将在JSON字符串中被用作缩进字符。同样缩进字符串长度不能超过10个字符长。

var people={
"name":"zzmm",
"age":29,
"year":2016,
"school":[
"zzzxxx",
"hunan"
],
"edition":3
};
//JSON.stringify()第三个参数是数值。
var jsonText=JSON.stringify(people,null,"---");


保存在jsonText中的字符串如下所示:

{

---"name": "zzmm",

---"age": 29,

---"year": 2016,

---"school": [

------"zzzxxx",

------"hunan"

---],

---"edition": 3

}

(3)toJSON()方法

可以给对象定义toJSON()方法,返回其自身的JSON数据格式。

var people={
"name":"zzmm",
"age":29,
"year":2016,
"school":[
"zzzxxx",
"hunan"
],
"edition":3,
toJSON:function(){
return this.name;
}
};
var jsonText=JSON.stringify(people);
alert(jsonText);//"zzmm"


3、解析选项

JSON.parse()方法也可以接收另一个参数,该参数是一个函数,将在每个键值对儿上调用。

var people={
"name":"zzmm",
"age":29,
"year":2016,
"school":[
"zzzxxx",
"hunan"
],
"edition":3,
releaseDate:new Date(2011,11,1)
};
var jsonText=JSON.stringify(people);
console.log(jsonText);


结果为:

{"name":"zzmm","age":29,"year":2016,"school":["zzzxxx","hunan"],"edition":3,"releaseDate":"2011-11-30T16:00:00.000Z"}

var people={
"name":"zzmm",
"age":29,
"year":2016,
"school":[
"zzzxxx",
"hunan"
],
"edition":3,
releaseDate:new Date(2011,11,1)
};
var jsonText=JSON.stringify(people);
//JSON字符串解析为原生JavaScript值
var peopleCopy=JSON.parse(jsonText,function(key,value){
if(key=="releaseDate"){
return new Date(value);
}else{
return value;
}
});
alert(peopleCopy.releaseDate.getFullYear());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: