json是一種輕量級(jí)的數(shù)據(jù)交換格式,它基于 ECMAScript 規(guī)范的一個(gè)子集,采用完全獨(dú)立于編程語(yǔ)言的文本格式來(lái)存儲(chǔ)、表示、傳輸數(shù)據(jù)。json的語(yǔ)法與JavaScript語(yǔ)法及其相似。
json語(yǔ)法規(guī)則:
1.對(duì)象表示為鍵值對(duì)
2.數(shù)據(jù)由逗號(hào)分割
3.花括號(hào)保存對(duì)象
4.方括號(hào)保存數(shù)組
json語(yǔ)法示例:
var str = {
"name" : "wgq",
"age" : "18",
"arg" : [
{ "teacher" : "ce" ,"firstname" : "wang"},
{ "teacher2" : "ce" ,"firstname2" : "wang"}
]
}
在javascript中存在兩種json數(shù)據(jù)方式:
1.json字符串
2.json對(duì)象
其實(shí)json字符串用來(lái)進(jìn)行數(shù)據(jù)傳輸(對(duì)象無(wú)法進(jìn)行傳輸),json對(duì)象用來(lái)進(jìn)行對(duì)內(nèi)容的表達(dá)輸出。
通過(guò)JSON.parse()函數(shù)可以把json字符串轉(zhuǎn)化為json對(duì)象,通過(guò)JSON.stringify()可以把json對(duì)象轉(zhuǎn)化為json字符串。下面我們來(lái)詳細(xì)介紹這兩個(gè)函數(shù)。
JSON.parse()
JSON.parse() 方法解析一個(gè)JSON字符串,構(gòu)造由字符串描述的JavaScript值或?qū)ο蟆?/p>
語(yǔ)法:JSON.parse(str[, fn]);
參數(shù):
str:要被解析的JSON字符串。
fn(可選):函數(shù),可以在返回之前對(duì)解析的原始值進(jìn)行改造。
首先 使用JSON.parse(),不帶fn
//str為上面的json字符串
var obj = JSON.parse(str);
console.log(obj);
// {
// name : "wgq",
// age : "18",
// arg : [
// { teacher : "ce" ,firstname : "wang"},
// { teacher2 : "ce" ,firstname2 : "wang"}
// ]
// }
可以看到obj的屬性少了雙引號(hào),它變成了json對(duì)象。
接下來(lái)使用fn :
fn(可選函數(shù))帶兩個(gè)參數(shù)k和v,k是鍵,v是值。
當(dāng)解析字符串的每一個(gè)屬性時(shí),函數(shù)會(huì)按照解析的順序(從最里面的屬性開(kāi)始,一級(jí)一級(jí)往外)分別調(diào)用fn函數(shù)(即解析一個(gè)屬性調(diào)用一次fn函數(shù))。
//str為上面的json字符串
var obj = JSON.parse(str,function(k,v){
if( k === "name"){
v = "123";
}
return v;
});
console.log(obj);
// {
// name : "123",
// age : "18",
// arg : [
// { teacher : "ce" ,firstname : "wang"},
// { teacher2 : "ce" ,firstname2 : "wang"}
// ]
// }
上面代碼寫(xiě)到,當(dāng)遍歷到屬性name時(shí),把name的值變?yōu)椤?23”。
函數(shù)解析順序:
JSON.parse(str,function(k,v){
conlose.log(k);
return v;
});
// name
// age
// teacher
// teacher2
// arg
// " "
由此可以看出,解析式從最最里層的屬性開(kāi)始,一級(jí)級(jí)往外,最終到達(dá)頂層。
fn的小知識(shí)點(diǎn):
當(dāng)遍歷到最頂層時(shí),k的值為空字符串。
如果返回undefined,則當(dāng)前屬性會(huì)從所屬對(duì)象中刪除。
JSON.stringify()
JSON.stringify() 方法將一個(gè)JSON對(duì)象轉(zhuǎn)換為一個(gè)JSON字符串
語(yǔ)法:JSON.stringify(str [,fn[, space]])
參數(shù):
str : 要被解析的json對(duì)象。
fn(可選) : 函數(shù)或者數(shù)組,在序列化的過(guò)程中,被序列化的屬性都過(guò)經(jīng)過(guò)該函數(shù)的轉(zhuǎn)化和處理。如果第二個(gè)參數(shù)為數(shù)組,則序列化的json字符串只保留數(shù)組中的屬性名。如果該參數(shù)為null或者未聲明,則所有屬性都會(huì)被序列化。
spance(可選) : 指定縮進(jìn),可以是數(shù)字或者字符串。數(shù)字最高為10,字符串也最高取10個(gè)。
首先使用JSON.stringify()
//obj為上面的json對(duì)象
var jsonstr = JSON.parse(obj);
console.log(jsonstr);
// {
// "name" : "wgq",
// "age" : "18",
// "arg" : [
// { "teacher" : "ce" ,"firstname" : "wang"},
// { "teacher2" : "ce" ,"firstname2" : "wang"}
// ]
// }
這里可以看到,本來(lái)為json對(duì)象的obj又重新變回了json字符串。
使用fn
fn的函數(shù)使用跟JSON.parse()差不多,可以參考上面所寫(xiě)內(nèi)容。
如果fn為數(shù)組:
數(shù)組的值代表json序列化字符串的屬性名。
//obj為上面的json對(duì)象
var jsonstr = JSON.parse(obj,["name","age"]);
console.log(jsonstr);
// {
// "name" : "wgq",
// "age" : "18",
// }
上面代碼可以看到,只有在數(shù)組中出現(xiàn)的值就是json字符串中出現(xiàn)的屬性名。
使用space參數(shù):
space 參數(shù)用來(lái)控制結(jié)果字符串里面的間距。如果是一個(gè)數(shù)字, 則在字符串化時(shí)每一級(jí)別會(huì)比上一級(jí)別縮進(jìn)多這個(gè)數(shù)字值的空格(最多10個(gè)空格);如果是一個(gè)字符串,則每一級(jí)別會(huì)比上一級(jí)別多縮進(jìn)用該字符串(或該字符串的前十個(gè)字符)。
var obj ={
name : "wgq"
}
var str = JSON.stringify(obj)
console.log(str)// {"name":"wgq"}
var str2 = JSON.stringify(obj,null," ");
console.log(str2)
//{
// "name":"wgq"
//}
序列化注意事項(xiàng):
1.非數(shù)組對(duì)象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中(即序列號(hào)后,順序會(huì)亂)
2.布爾值、數(shù)字、字符串的包裝對(duì)象在序列化過(guò)程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值。
3.undefined、任意的函數(shù)以及 symbol 值,在序列化過(guò)程中會(huì)被忽略(出現(xiàn)在非數(shù)組對(duì)象的屬性值中時(shí))或者被轉(zhuǎn)換成 null(出現(xiàn)在數(shù)組中時(shí))。
4.所有以 symbol 為屬性鍵的屬性都會(huì)被完全忽略掉,即便 replacer 參數(shù)中強(qiáng)制指定包含了它們。
5.不可枚舉的屬性會(huì)被忽略。