jiangbo0 2016-06-13
一种结构化数据的格式,与JavaScript有相同的语法形式,但不属于JavaScript。支持多种编程语言。
1、语法
JSON有3种类型的值:简单值、对象和数组。
简单值:字符串、数值、布尔值、null(JSON不支持JavaScript的特殊值undefined)
对象:一组无序键值对。值可为简单值,或对象和数组。
数组:一组有序键值对。值可为简单值,或对象和数组
JSON不支持变量、函数和对象实例。
1-1、简单型
JSON字符串必须使用双引号(单引号会导致语法错误)
1-2、对象
JSON对象的属性必须使用双引号:
{"name":"xiaoming","age":24
}
与JavaScript对象字面量的区别:无声明变量;无末尾分号。
1-3、数组
同样无声明对象;无末尾分号。
2、解析与序列化
2-1、JSON对象
早期JSON解析器使用JavaScript的eval()函数解析、解释并返回JavaScript对象和数组。ECMAScript5定义了全局对象JSON(支持IE8+等主流浏览器)。
eval()对JSON数据结构求值存在风险,可能会执行恶意代码,故早期浏览器可使用shim:https://github.com/douglascrockford/JSON-js
JSON对象的两个方法:stringify()、parse()
stringify():将JavaScript对象序列化为JSON字符串。
stringify()
JSON.stringify()输出的JSON字符串默认不包含缩进、空格符和换行符。
序列化JavaScript对象时,所有函数、原型成员和值为undefined的属性都会被忽略。
parse():将JSON字符串解析为原生JavaScript值
传给JSON.parse()的字符串不是有效JSON时,会抛出错误。
※即使stringify()之前和parse()后两个对象属性相同,也是两个完全独立的对象。
2-2、序列化
JSON.stringify()有3个参数:JavaScript对象、过滤器、控制缩进等格式化
1-过滤器(过滤结果):数组、函数
数组过滤器:JSON.stringify()的结果将只包含数组中列出的属性:
数组过滤器
函数过滤器:函数有2个参数,为属性(键)名和属性值。属性名只能为字符串,非键值对结构的键名为空字符串。
通过函数处理特定的属性。序列化的对象中的每个对象都要进过过滤器。
函数过滤器
☆实际上,第一次调用函数过滤器时,传入的是一个空字符串,值为这个book对象
2-字符串缩进
JSON.stringify()的第3个参数用于控制结果的缩进和空白符。(换行符会在传入有效缩进参数时,自动添加)
当为数值时,表示每级缩进的空格数;
当为非数值时,做为缩进字符(不再使用空格缩进)。
※最大缩进数和缩进字符为10,超过时自动转换为10
ViewCode
3-toJSON()方法
toJSON()方法可用于返回任何值;也可作为过滤器的补充,进行根精确的自定义序列化需求。
例子
☆☆☆☆☆
☆将一个对象传入JSON.stringify()后的序列化顺序:
①若存在而且能通过toJSON()获取有效值,将先调用该方法。否则返回对象本身;
②若存在第2参数,将①返回的值传入过滤器;
③对②返回的每个值进行相应的序列化;
④若存在第3参数,对序列化后的数据进行相应格式化。
2-3、解析
JSON.parse()2个参数:JSON对象、函数(还原函数‘reviver’,与序列化的替换函数'replacer'具有相同签名:2个参数——键与值)
还原函数:若此函数返回undefined,将会删除相应的键,若返回其他值,则会被插入结果中。
JSON是一个轻量级的数据格式,可以简化表示数据结构的工作量。在实际工作中,我们经常用它来传递数据,不过对于其使用的一些细节还是需要注意的。在ECMAScript5中定义了原生的JSON对象,可以用来将对象序列化为JSON字符串,或者将JSON数据解析为javascript对象。
一、JSON语法
JSON可以用来表示三种类型的值:简单值、对象和数组。对象和数组一般是JSON结构的最外层形式。
1.JSON简单值
可以在JSON中表示字符串、数值、布尔值、null。
例如:
5//数值类型
"hellojson"//字符串类型
注意:
①JSON不支持js中的特殊值undefined;
②JSON字符串必须使用双引号,不能使用单引号。
③在实际应用中,JSON一般用来表示较复杂的数据结构,而简单值一般用作复杂数据结构中的一部分。
2.对象
JSON对象与JavaScript对象字面量对象的语法是类似的。
//JavaScript对象字面量表示
varjsWeatherinfo={
city:"北京",
cityid:"101010100",
weather:"多云转晴"
//JSON对象
{
"city":"北京",
"cityid":"101010100",
"weather":"多云转晴"
}
但是有几点不同:
①JSON中没有变量的概念,所以没有声明变量;
②JSON末尾没有分号;
③JSON对象中的属性名一定要使用双引号,而JavaScript对象中的属性引号是可有可无的。
3.数组
JSON数组采用的是javascript的数组字面量形式.
//JavaScript数组
varresult=[1,true,"today"];
//JSON数组
[1,true,"today"]
区别:JSON数组没有末尾的分号,也没有声明变量.
二、JSON序列化
1.JSON对象
JavaScript的eval()函数可以用来解析JSON并返回JavaScript对象,不过eval()对JSON结构求值是存在风险的.因此,在ECMAScript5中新增了全局的JSON对象.JSON对象有两个方法:stringify()和parse().
stringify()用于把JavaScript对象序列化为JSON字符串;
parse()用于把JSON字符串解析为原生的JavaScript值.
varweather={
'city':'北京',
'cityid':'101010100',
'temp1':'31℃',
'temp2':'20℃',
'weather':'多云转晴',
'img1':'d1.gif',
'img2':'n0.gif',
'ptime':'11:00'
};
vartext=JSON.stringify(weather);
varjson=JSON.parse(text);
json.weather;//"多云转晴"
2.JSON.stringify()
JSON.stringify()方法有三个参数:
第一个参数是要序列化的JavaScript对象;
第二个参数是过滤器,可以是一个数组或者函数;
第三个参数是一个布尔值,表示是否在JSON字符串中保留缩进.
①过滤器
如果过滤器参数是数组,那么stringify()结果中只包含该数组中列出的属性.
varweather={
'city':'北京',
'cityid':'101010100',
'temp1':'31℃',
'temp2':'20℃',
'weather':'多云转晴',
'img1':'d1.gif',
'img2':'n0.gif',
'ptime':'11:00'
};
vartext=JSON.stringify(weather,["city","weather","temp1","temp2"]);
//结果:"{"city":"北京","weather":"多云转晴","temp1":"31℃","temp2":"20℃"}"
如果过滤器是函数,传入的函数有两个参数:属性名和属性值.根据属性名来判断如何处理序列化对象中相应的属性.如果函数返回了undefined,那么相应的属性就会被忽略.
vartext1=JSON.stringify(weather,function(key,value){
switch(key){
case'temp1':
return'最高温度'+value;
case'temp2':
return'最低温度'+value;
case'img1':
case'img2':
case'ptime':
returnundefined;//属性被忽略
default:
returnvalue;
}
});
//结果:"{"city":"北京","cityid":"101010100","temp1":"最高温度31℃","temp2":"最低温度20℃","weather":"多云转晴"}"
③字符串缩进
JSON.stringify()第三个参数用来控制结果中的缩进情况.
如果缩进参数传入的是数值,表示每个json字段缩进的空格数,但是最大缩进空格数不超过10.
vartext2=JSON.stringify(weather,null,5)
如果缩进参数传入的是字符串,则表示JSON字符串中每个级别都使用该字符串作为缩进字符.不过该字符串也不能超过10个字符长.
vartext3=JSON.stringify(weather,null,"--")
④toJSON()方法
如果JSON.stringify()不能满足某些对象的序列化需求,可以给对象自定义toJSON方法,返回其自身的JSON数据格式。
varweather={
'city':'北京',
'cityid':'101010100',
'temp1':'31℃',
'temp2':'20℃',
'weather':'多云转晴',
toJSON:function(){
returnthis.city+this.weather+",最高温度"+this.temp1+",最低温度"+this.temp2;
}
};
JSON.stringify(weather);//""北京多云转晴,最高温度31℃,最低温度20℃""
综合以上几种情况,JSON.stringify()序列化对象的顺序如下:
①如果对象存在toJSON方法且能返回有效值,则调用该方法;否则,仍然按照默认顺序执行序列化。
②如果stringify()存在第二个参数,应用这个过滤器;
③对第②步返回的每个值进行序列化;
④如果存在第三个参数,执行相应的格式化。
三、JSON解析
JSON.parse()用来将JSON字符串解析成JavaScript对象。
该方法第一个参数要解析的JSON字符串;
第二个参数是一个函数还原函数。还原函数有两个参数key和value。如果还原函数返回undefined,则表示将该属性从结果中删除;如果返回其它值,则将该值插入到结果当中。在将日期字符串转换为Date对象时,经常用到还原函数.
varjson={
'city':'北京',
'cityid':'101010100',
'temp1':'19℃',
'temp2':'32℃',
'weather':'晴',
'ptime':newDate()
};
vartext=JSON.stringify(json);
JSON.parse(text,function(key,value){
switch(key){
case'ptime':
returnnewDate(value);//返回日期对象
case'cityid':
returnundefined;//删除该属性
default:
returnvalue;
}
});
1.XHR对象
①IE6需要使用MSXML库中的一个ActiveX对象实现,而其他浏览器原生支持XHR对象。
functioncreateXHR(){
if(typeofXMLHttpRequest!="undefined"){
returnnewXMLHttpRequest();
}elseif(typeofActiveXobject!="undefined"){
if(typeofarguments.callee.activeXString!="string"){
varversions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"];
for(vari=0,len=versions.length;I<len;i++){
try{
varxhr=newActiveXObject(versions[i]);
Arguments.callee.activeXString=versions[i];
returnxhr;
}catch(ex){
//跳过
}
}
}
returnnewActiveXObject(arguments.callee.activeXString);
}else{
thrownewError("NoXHRobjectavailable");
}
}
1.1XHR的用法
①open()方法
□接受3个参数:要发送的请求的类型(“get”、“post”等)、请求的URL和表示是异步发送请求的布尔值。
□参数URL是相对于执行代码的当前页面(当然也可以使用绝对路径);
□调用open()方法并不会真正发送请求,而只是启动一个请求以备发送。
②send()方法
□要发送特定的请求,必须使用send()方法启动。
□接受一个参数,即要作为请求主体发送的数据。如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必须的。
□调用send()之后,请求就会被分派到服务器。
③相应的数据会自动填充XHR对象的属性,相关的属性简介如下:
□responseText:作为相应主体被返回的文本。
□responseXML:如果响应的内容是“text/xml”或“application/xml”,这个属性中将保存含着响应数据的XMLDOM文档。
□status:响应的HTTP状态。
□statusText:HTTP状态的说明。
④处理响应的判断
□检查status属性,以确定响应成功返回。
□HTTP状态代码为200是成功的标志,此时responseText、responseXML应能访问。
□HTTP状态代码为304表示请求的资源没修改,可使用缓存值。
⑤同步请求
xhr.open("get","example.txt",false);
xhr.send(null);
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
alert(xhr.statusText);
}else{
alert("Requestwasunsuccessful:"+xhr.status);
}
⑥异步请求
1)发送异步请求还需要检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段。取值如下:
□0:未初始化。尚未调用open()方法。
□1:启动。已调用open()方法,未调用send()方法。
□2:发送。已调用send()方法,但尚未接收到响应。
□3:接收。已接收到部分响应数据。
□4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
2)readyState值的变化会触发readyStatechange事件。由于并非所有浏览器支持DOM2级方法,因此用DOM0级添加处理程序。
varxhr=createXHR();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if((xhr.staus>=200&&xhr.status<300)||xhr.status==304){
alert(xhr.responseText);
}else{
alert("Requestwasunsuccessful:"+xhr.status);
}
}
};
xhr.open("get","example.txt",true);
xhr.send(null);
⑦在接收到响应之前还可以调用abort()方法取消异步请求。xhr.abort();
1.2HTTP头部信息
XHR对象提供了操作“请求头部”和“响应头部”信息的方法。
①请求头部
1)请求头部信息
□Accept:浏览器能够处理的内容类型。
□Accept-Charset:浏览器能够显示的字符集。
□Accept-Encoding:浏览器能够处理的压缩编码。
□connection:浏览器与服务器之间连接的类型。
□Cookie:当前页面设置的任何cookie。
□Host:发出请求的页面所在的域。
□Referer:发出请求的页面的URI。
□User-Agent:浏览器的用户代理字符串。
②setRequestHeader()方法可以设置自定义的请求头部信息。
□接收两个参数:头部字段名称和头部字段的值。
□要成功发送请求头部信息,必须在调用open()方法之后且调用send()方法之前。
③getResponseHeader()方法,传入头部字段名称,可以取得相应的响应头部信息。
④getAllResponseHeader()方法,取得一个包含所有头部信息的长字符串。
1.3GET请求
①常用语服务器查询信息。
②GET请求经常会发生查询字符串格式问题。查询字符串中每个参数的名称和值都必须使用encodeURIComponent()进行编码。
③辅助向现有URL末尾添加查询字符串参数:
functionaddURLParam(url,name,value){
url+=(url.indexOf("?")==-1?"?":"&");
url+=encodeURIComponent(name)+"="+encodeURIComponent(value);
returnurl;
}
1.4POST请求
①通常用于向服务器发送应该被保存的数据。
②xhr.open("post","example.php",true);发送post请求的第二步就是向send方法中传入某些数据。
1.5浏览器差异
①IE
□IE为XHR对象添加了一个timeout属性,表示请求在等待响应。
□规定时间内没有接收到响应,就出发timeout事件,进而调用ontimeout事件处理程序。
②Firefox
1)load事件
2)progress事件
2.跨域请求
①IE中XDomainRequest对象
1)XDR与XHR区别
□cookie不会随请求发送,也不会随响应返回。
□只能设置请求头部信息中的Content-Type字段。
□不能访问响应头部信息。
□只支持GET和POST请求。
□XDR只能访问Access-Control-Allow-Origin头部设置为有当前域的资源。
2)所有XDR请求都是异步执行的,不能创建同步请求。
□返回请求之后,会触发load事件,响应的数据也会保存在response属性中。
□接收到响应后,只能访问响应的原始文本,没有办法确定响应的状态代码。
□响应有效会触发load事件,如果失败(包括响应中缺少Access-Control-Origin头部)就会触发error事件。
□XDR也支持timeout属性以及ontimeout事件处理程序。
□为了支持POST请求,XDR对象提供了ontentType属性,用来表示发送数据的格式。
□在请求返回前调用abort()方法可终止请求。
varxdr=newXDomainRequest();
xdr.onload=function(){
alert(xdr.responseText);
};
xdr.timeout=1000;
xdr.ontimeout=function(){
alert("Requesttooktoolong.");
};
xdr.open("get","http://www.xx.com/page/");
xdr.send(null);
②Firefox
1)要求远程资源有权决定自身是否可以被远程浏览器访问。
□这需要通过设置Access-Contro-Allow-Origin头部实现。
□要访问另一个域资源,可以使用标准XHR对象,并为open()方法传入一个绝对URL。
2)与IE中XDR对象不同,跨域XHR对象允许访问status和statusText属性,也支持同步请求。
3)跨域XHR的额外限制如下:
□不能使用setRequestHeader()设置自定义头部。
□不会发送也不会接受cookie
□getAllRequestponseHeaders()方法只能返回空字符串。
3.JSON
①JSON是纯文本,而不是JavaScript代码。JSON的设计意图在服务器端构建格式化的数据,然后再将数据发送给浏览器。
②由于JSON在JavaScript中相当于对象和数组,因此JSON字符串可以传递给eval()函数,让其解析并返回一个对象或数组的实例。
③如果你是自己编写代码来对JSON求值,最好将输入文本放在一对圆括号中。因为eval()在对输入的文本求值时,是将其作为JS代码而非数据格式看待。在对以左花括号开头的对象求值时,就好像是遇到一个没有名字的JavaScript语句,会导致错误。将文本放在一对圆括号中可以解决这个问题,因圆括号表示值而不是语句。
varobject1=eval("{}");//抛出错误
varobject2=eval("({})");//没有问题
varobject3=eval("("+jsonText+")");//通用解决方案
3.1在Ajax中使用JSON
①DouglasCrockford的JSON序列化器/解析器。www.json.org/js.html
②在上述库中,有一个全局JSON对象,有两个方法:parse()和stringify()。
③parse()方法:
□两个参数:JSON文本和一个可选的过滤函数。在传入的文本是有效地JSON情况下,parse()方法返回传入数据的一个对象表示。
□例子:varobject=JSON.parse("{}");与直接使用eval()不同的是,这里不需要传入的文本家圆括号(内部自动处理)。
□第二个参数是一个函数,这个函数以一个JSON键和值作为参数。要想让作为参数的键出现在结果对象中,该函数必须返回一个值。
varjsonText="{\"name\":\"Nicholas\",\"age\":29,\"author\":true}";
varobject=JSON.parse(jsonText,function(key,value){
switch(key){
case"age":returnvalue+1;
case"author":returnundefined;
default:returnvalue;
}
});
alert(object.age);//30
alert(object.author);//undefined
④JSON同样也是向服务器发数据的流行格式。发送数据时,一般会把JSON放到POST请求主体中,而JSON对象的stringify()方法正是为此而设计。
⑤stringify()方法:
□三个参数:要序列化的对象、可选的替换函数(用于替换未受支持的JSON值)和可选的缩进说明符(可以是每个级别缩进的空格数,也可以是用来缩进的字符)。
varcontact={
name:"NicholasC.Zakas",
email:"[email protected]"
};
varjsonText=JSON.stringify(contact);
alert(jsonText);
□JSON序列化支持的类型:字符串、数值、布尔值、null、对象、数组和Date(Date将被换成字符串形式)。其他不支持类型将被移除,可通过stringify()第二个参数所传入的函数改变行为。
3.2安全
①JSON缺点:使用eval(),有可能受到XSS攻击。
②建议使用Crockford的库,可妥当解析JSON字符串,过滤其中恶意代码。降低遭受代码式XSS攻击的可能性。
理解Json语法、解析Json、序列化Json
JSON(JavaScriptObjectNotation对象表示法)是一种结构化数据的格式,与JavaScript有相同的语法形式,但不属于JavaScript。支持多种编程语言。
20.1语法
JSON的语法可以表示以下3种类型的值:
简单值:字符串、数值、布尔值、null(JSON不支持JavaScript的特殊值undefined)。
对象:一组有序键值对。每个键值对儿中的值可为简单值,也可以使复杂数据类型的值。
数组:一组有序的值的列表,通过数值索引来访问其中的值。数组的值可为简单值、对象或数组。
JSON不支持变量、函数和对象实例。
20.1.1简单值
JS字符串与JSON字符串的最大区别是JSON字符串必须使用双引号(单引号会导致语法错误)。
布尔值和null也是有效的JSON形式。
20.1.2对象
JSON中的对象和JS字面量稍微有一些不同。JSON中的对象要求给属性加引号:
{"name":"Nicholas","age":29}
与JS的对象字面量相比,JSON对象有两个地方不一样。
1.没有声明变量(JSON中没有变量的概念)。
2.没有末尾的分号。
JSON中也可以像下面这样在对象中嵌入对象:
{"name":"Nicholas","age":29,"school": {"name":"MerrimackCollege","location":"NorthAndover,MA"}}
20.1.3数组
JSON数组采用的就是JS种的数组字面量形式。如:
[25,"hi",true]
JSON数组也没有变量和分号。把数组和对象结合起来,可以构成更复杂的数据集合。(其实也就是我们平时做需求时候经常用到的形式~)
20.2解析与序列化
JSON流行的原因是,与XML数据结构相比,可以把JSON非常方便的解析为有用的JS对象,之后非常容易取到我们想要的数据。
20.2.1JSON对象
早期的JSON解析器基本上就是使用JS的eval()函数。由于JSON是JS语法的子集,eval()函数可以解析、解释并返回JS对象和数组。
JSON对象有两个方法:stringify()和parse()。这两个方法分别用于把JS对象序列化为JSON字符串和把JSON字符串解析为原生JS值。例如:
varbook={title:"ProfessionalJavaScript",authors:["NicholasC.Zakas"],edition:3,year:2011};varjsonText=JSON.stringify(book);
默认情况下,JSON.stringify()输出的JSON字符串不包含任何空格字符或缩进,因此保存在jsonText中的字符串如下所示:
{"title":"ProfessionalJavaScript","authors":["NicholasC.Zakas"],edition:3,year:2011}
在序列化JS对象时,所有函数、原型成员和值为undefined的属性都会被忽略。结果中最终都是值为有效JSON数据类型的实例属性。
将JSON字符串直接传递给JSON.parse()就可以得到相应的JS值。
varbookCopy=JSON.parse(jsonText);
创建的bookCopy与book具有相同的属性,但它们两个是独立的、没有任何关系的对象。
如果传给JSON.parse()的字符串不是有效的JSON,该方法会抛出错误。
20.2.2序列化
除了JS对象,JSON.stringify()还有两个参数,一个是过滤器,可以是数组或函数,另一个是选项,表示是否在JSON字符串中保留缩进。
1.过滤器(过滤结果):数组、函数
数组过滤器:JSON.stringify()的结果将只包含数组中列出的属性:
varbook={title:"ProfessionalJS",authors:["NicholasC.Zakas"],edition:3,year:2011};varjsonText=JSON.stringify(book,["title","edition"]);
函数过滤器:函数有2个参数,为属性(键)名和属性值。属性名只能为字符串,非键值对结构的键名为空字符串。
通过函数处理特定的属性。序列化的对象中的每个对象都要经过过滤器。
varjsonText=JSON.stringify(book,function(key,value){switch(key){case"authors":returnvalue.join(",")case"year":return5000;case"edition":returnundefined;default:returnvalue;}});
如果键为”authors”,将数组连接为一个字符串,如果键为”year”,将其值设为5000,如果键为”edition”,通过返回undefined删除该属性,最后要提供defaule项。返回:
{"title":"ProfessionalJS","authors":"NicholasC.Zakas","year":5000}
实际上,第一次调用函数过滤器时,传入的是一个空字符串,值为这个book对象。
2.字符串缩进
JSON.stringify()的第3个参数用于控制结果的缩进和空白符。(换行符会在传入有效缩进参数时,自动添加)
当为数值时,表示每级缩进的空格数;当为非数值时,做为缩进字符(不再使用空格缩进)。
最大缩进数和缩进字符为10,超过时自动转换为10。
varjsonText=JSON.stringify(book,null,"--");
效果:
{----“title”:"ProfessionalJS",----“authors”:[--------"NicholasC.Zakas"----],----“edition”:3,----“year”:2011}
3.toJSON()方法
通过对象上调用toJSON()方法可返回其自身的JSON数据格式,可用于返回任何值;也可作为过滤器的补充,进行根精确的自定义序列化需求。
varbook={"title":"ProfessionalJS","authors":["NicholasC.Zakas"],edition:3,year:2011,toJSON:function(){returnthis.title;}};varjsonText=JSON.stringify(book);
以上代码在book对象上定义了一个toJSON()方法,返回图书的书名。
toJSON()方法会在序列化之前先执行。
toJSON()方法可以作为函数过滤器的补充,将一个对象传入JSON.stringify()后的序列化顺序:
①若存在而且能通过toJSON()获取有效值,将先调用该方法。否则返回对象本身;
②若存在第2参数,将①返回的值传入过滤器;
③对②返回的每个值进行相应的序列化;
④若存在第3参数,对序列化后的数据进行相应格式化。
20.2.3解析选项
JSON.parse()2个参数:JSON对象、函数(还原函数‘reviver’,与序列化的替换函数'replacer'具有相同签名:2个参数——键与值)
还原函数:若此函数返回undefined,将会删除相应的键,若返回其他值,则会被插入结果中。
varbook={"title":"ProfessionalJavaScript","authors":["NicholasC.Zakas"],edition:3,year:2011,releaseDate:newDate(2011,11,1)};varjsonText=JSON.stringify(book);varbookCopy=JSON.parse(jsonText,function(key,value){if(key=="releaseDate"){returnnewDate(value);}else{returnvalue;}});
releaseDate属性保存着一个Date对象,序列化后,在bookCopy中又被还原成一个Date对象,故bookCopy.releaseDate才有一个Date对象,才可以调用getFullYear()方法。
20.3小结
JSON是一个轻量级的数据格式,可以简化表示复杂数据结构得工作量。
JSON.stingify()和JSON.parse()方法分别用来实现,将对象序列化为JSON字符串或者将JSON数据解析为JS对象。