媒介
JSON(JavaScript Object Notation,JavaScript對象示意法)是JavaScript的一個嚴厲的子集,利用了JavaScript中的一些情勢來示意構造化數據。
JSON是一種數據花樣,不是一種編程言語,雖然具有雷同的語法花樣,但JSON並不從屬於JavaScript,也並不只要JavaScript才運用JSON,許多編程言語都有針對JSON的剖析器和序列化器。
一、JSON
JSON的語法能夠示意三種範例的值:簡樸值、對象和數組。
簡樸值
最簡樸的JSON數據情勢就是簡樸值,如:
JSON示意數值7的體式格局:
7
JSON示意字符串的體式格局:
"Hello Miyang!"
JavaScript字符串與JSON字符串最大的區分在於,JSON字符串必需運用雙引號。
布爾值和null也是有效的JSON情勢。
對象
我們來對照一下JSON中的對象和JavaScript字面量:
JavaScript字面量:
var person = {
name: "Miyang",
age: 21
};
或
var person = {
"name": "Miyang",
"age": 21
};
在JSON中的對象請求必需給屬性加引號:
{
"name": "Miyang",
"age": 21
}
比擬二者,JSON沒有聲明變量,其次,末端也沒有分號,最主要的一點,對象的屬性必需加雙引號。
在實際運用中,我們常常會碰到如許的JSON數據:
{
"name": "Miyang",
"age": 21,
"location": {
"name": "Ping guo yuan",
"city": "Beijing"
}
}
雖然該JSON中存在兩個name屬性,但由於它們離別屬於差別的對象,因而沒有問題。同一個對象中相對不應該湧現兩個同名屬性。
數組
在JSON中,能夠採納與JavaScript雷同的語法示意一個數組:
["Miyang", 21, true]
一樣的,JSON數組也沒有變量和分號,數組和對象結合起來,能夠組成較為龐雜的數據鳩合。
[
{
"name": "Miyang",
"age": 21,
"hobby": ["HTML", "CSS", "Javascript"]
},
{
"name": "Miyang",
"age": 21,
"hobby": ["HTML", "CSS", "Javascript"]
},
{
"name": "Miyang",
"age": 21,
"hobby": ["HTML", "CSS", "Javascript"]
}
]
二、剖析與序列化
JSON的盛行,更主要的原因是能夠把JSON數據構造剖析為有效的JavaScript對象,相對於XML數據構造來講上風極為顯著。如我們能夠經由過程以下要領來獵取某個屬性:
person[0].name
JSON對象
初期JSON剖析器基礎經由過程JavaScript的eval()
函數,然則存在風險,由於可能會實行一些惡意代碼。從ECMAScript5最先,定義了全局對象JSON,能夠更輕易的對JSON舉行剖析與序列化。
JSON.stringify()
該要領能夠將JavaScript對象序列化為一個JSON字符串,默許情況下,輸出的字符串不包括任何空格字符或縮進,如:
var json = {
"name": "Miyang",
"age": 21
};
console.log(JSON.stringify(json));
// 輸出效果
{"name":"Miyang","age":21}
在序列化JavaScript對象時,一切函數即原型成員都會被故意疏忽,不體現在效果中,值為undefined的任何屬性也會被跳過,如:
var json = {
"name": "Miyang",
"age": 21,
"test": undefined
};
console.log(JSON.stringify(json));
// 輸出效果
{"name":"Miyang","age":21}
JSON.parse()
該要領能夠將JSON字符串轉換為JSON對象,如:
var jsonTest = '{"name": "Miyang","age": 21,"test": "undefined"}';
console.log(JSON.parse(jsonTest));
// 輸出效果
{ name: 'Miyang', age: 21, test: 'undefined' }
假如傳給JSON.parse()的字符串不是有效的JSON,該要領會拋出毛病。
序列化選項
JSON.stringfiy()
還能夠吸收兩個參數,用於指定以差別體式格局序列化JavaScript對象。
第一個參數是過濾器,能夠是一個數組,也能夠是一個函數。
第二個參數是一個選項,示意是不是在JSON字符串中保存縮進。
過濾效果
假如過濾器參數是數組,那末返回的效果就只包括數組中列出的屬性,如:
var json = {
"name": "Miyang",
"age": 21
};
console.log(JSON.stringify(json, ["name"]));
// 輸出效果
{"name":"Miyang"}
假如過濾器參數是函數,則該函數能夠吸收兩個參數,屬性名和屬性值,隨後依據函數對效果舉行過濾,如:
var json = {
"name": "Miyang",
"age": 21,
"hobby": ["HTML", "CSS"]
};
console.log(JSON.stringify(json, function(key, value) {
switch(key) {
case "name":
return value + "!!!";
case "age":
return 18;
case "hobby":
return undefined;
default:
return value;
}
}));
// 輸出效果
{"name":"Miyang!!!","age":18}
這裏注重,假如函數返回了undefined,那末響應的屬性會被疏忽。
字符串縮進
JSON.stringify()
的第三個要領用於控制效果中的縮進和空白符,假如該參數是一個數值,則示意每一個縮進的空格數,最大縮進為10,大於10的值會自動轉換為10。當傳入了有效縮進參數值,效果字符串就會包括換行符。
var json = {
"name": "Miyang",
"age": 21,
"hobby": ["HTML", "CSS"]
};
console.log(JSON.stringify(json, null, 2));
// 輸出效果
{
"name": "Miyang",
"age": 21,
"hobby": [
"HTML",
"CSS"
]
}
假如縮進參數是一個字符串,則這個字符串將在JSON字符串在作為縮進字符,一樣的,長度不能超過10個字符長,不然只显示前10個字符。
var json = {
"name": "Miyang",
"age": 21,
"hobby": ["HTML", "CSS"]
};
console.log(JSON.stringify(json, null, '-'));
// 輸出效果
{
-"name": "Miyang",
-"age": 21,
-"hobby": [
--"HTML",
--"CSS"
-]
}
toJSON()要領
當JSON.stringify()
不能滿足需求時,能夠給對象定義toJSON()
要領,返回其自身的JSON數據花樣。
var json = {
"name": "Miyang",
"age": 21,
"address": {
"city": "Beijing"
},
toJSON: function() {
return this.name;
}
};
console.log(JSON.stringify(json));
// 輸出效果
"Miyang"
能夠讓這個要領返回undefined,假如此時包括它的對象嵌入在另一個對象中,會致使它的值變成null,假如是頂級對象,則返回undefined。
var json = {
"name": "Miyang",
"age": 21,
"address": {
"city": "Beijing"
},
toJSON: function() {
return undefined;
}
};
console.log(JSON.stringify(json));
// 輸出效果
undefined
var json = {
"name": "Miyang",
"age": 21,
"address": {
"city": "Beijing",
toJSON: function() {
return undefined;
}
}
};
console.log(JSON.stringify(json));
// 輸出效果
{"name":"Miyang","age":21}
序列化內部事情遞次
我們須要相識一下序列化內部事情遞次,假定把一個對象傳入JSON.stringify()
,序列化該對象的遞次以下:
- 假如存在
toJSON()
要領而且能取得有效值,則挪用該要領,不然返回對象自身。 - 假如供應了第二個參數,運用這個函數過濾器,傳入的值是第1步返回的值。
- 對第2步返回的每一個值舉行響應的序列化。
- 假如供應了第三個參數,實行響應的花樣化。
剖析選項
JSON.parse()
也能夠吸收另一個參數,該參數是一個函數,對每一個鍵值對舉行挪用,被稱之為復原函數。一樣的,它吸收兩個參數,一個鍵和一個值,且須要返回一個值。
假如返回undefined,則示意要從效果中刪除響應的鍵,假如返回其他值,則將該值插進去到效果中,在將日期字符串轉換為Date對象時,常常用到復原函數。
var json = {
"name": "Miyang",
"age": 21,
"address": {
"city": "Beijing"
},
"date": new Date(2011, 11, 1)
};
var jsonText = JSON.stringify(json);
var jsonCopy = JSON.parse(jsonText, function(key, value) {
if(key === "date") {
return new Date(value);
}else {
return value;
}
});
console.log(jsonCopy.date.getTime());
// 輸出效果
1322668800000
結束語
JSON是一個輕量級的數據花樣,能夠簡化示意龐雜數據構造的事情量,相識其構造、控制JavaScript對其的操作要領,能夠更便利的舉行前背景交互或數據處理。
參考資料:JavaScript高等程序設計(第三版)第20章