JSON 全稱為 JavaScript Object Notation(JavaScript物件表示法),它利用與 JavaScript 物件相似的表示方法來表示資料。雖然 JSON 脫胎於 JavaScript,但是 JSON 並不屬於 JavaScript 的一部分,很多的語言都可以解析和序列化 JSON。
JSON 語法
JSON 可以表示以下三種型別的值:
-
簡單值
-
物件
-
陣列
簡單值包括字串、數值、布林值和 null。但是要注意的是 JSON 不能表示 JavaScript 當中的一種特殊值 undefinde。
物件,與 JavaScript物件相似,表示無序的鍵值對。鍵值對中的值可以是簡單值,也可以是物件或陣列。
陣列,與 JavaScript陣列相似,表示一組有序的值,陣列的值可以是簡單值,也可以是物件或陣列。
舉個例子:
{
"name": "acwong",
"age": 23,
"address": {
"province": "GuangDong",
"city": "GuangZhou"
},
"friends": ["bc", "cc", "dc"],
"blog": "http://acwong.org"
}
需要注意的是,也是與 JavaScript物件表示方法的不同之處,JSON 字串當中物件的屬性必須加上雙引號。
// 正確示範
{
"name": "acwong"
}
// 錯誤示範
{
name: "acwong"
}
// 單引號也是錯誤的
{
`name`: `acwong`
}
JavaScript 與 JSON
JSON 物件
在 JSON 誕生之初 JavaScript 處理 JSON 的方式基本就靠 eval()
函式。
eval()
函式可以解析 JSON 然後返回 JavaScript 陣列。但是由於 eval()
存在安全的風險,因此在 EMCAScript 5 開始有了一個新的全域性物件 JSON物件用來處理 JSON。
序列化 JSON
JavaScript 使用 JSON物件的 stringify()
方法來序列化 JSON。
var person = {
name: "acwong",
age: 23,
address: {
province: "GuangDong",
city: "GuangZhou"
},
friends: ["bc", "cc", "dc"],
blog: "http://acwong.org"
};
var jsonText = JSON.stringify(person);
console.log(jsonText);
// {"name":"acwong","age":23,"address":{"province":"GuangDong","city":"GuangZhou"},"friends":["bc","cc","dc"],"blog":"http://acwong.org"}
JSON.stringify()
方法在預設情況下輸出的 JSON字串不包含空格字元和縮排。
如果 JavaScript物件當中包含不被 JSON 支援的型別(如:undefined,函式)會自動被 stringigy()
方法忽略。
var person = {
name: "acwong",
blog: undefined,
todo: function() {
return "sleep";
}
};
var jsonText = JSON.stringify(person);
console.log(jsonText);
// {"name":"acwong"}
JSON.stringify()
方法包含三個引數,第一個引數就是要序列化的 JavaScript物件。第二個引數完成過濾輸出結果功能。第三個引數控制輸出字串的縮排。
過濾輸出結果
第二個引數完成過濾輸出結果功能。
當傳入的第二個引數為陣列時,輸出的 JSON字串只會保留包含在該陣列裡面的屬性值。
var person = {
name: "acwong",
age: 23,
address: {
province: "GuangDong",
city: "GuangZhou"
},
friends: ["bc", "cc", "dc"],
blog: "http://acwong.org"
};
var jsonText = JSON.stringify(person, ["name","blog"]);
console.log(jsonText);
// {"name":"acwong","blog":"http://acwong.org"}
當傳入的第二個引數為函式,該函式包含兩個引數,分別是 JavaScript物件的屬性名和屬性值。輸出的 JSON字串會受到該函式的返回值影響。
// 省略 person物件
var jsonText = JSON.stringify(person, function(key, value) {
if (key === "name") {
return "ac";
} else if (key === "age") {
value++;
return value;
} else {
return value;
}
});
console.log(jsonText);
// {"name":"ac","age":24,"address":{"province":"GuangDong","city":"GuangZhou"},"friends":["bc","cc","dc"],"blog":"http://acwong.org"}
控制縮排
第三個引數控制輸出字串的縮排。
當第三個引數傳入一個數值的時候,表示輸出字串縮排的空格數。
// 省略 person物件
var jsonText = JSON.stringify(person, null, 2);
console.log(jsonText);
// 輸出
{
"name": "acwong",
"age": 23,
"address": {
"province": "GuangDong",
"city": "GuangZhou"
},
"friends": [
"bc",
"cc",
"dc"
],
"blog": "http://acwong.org"
}
當第三個引數傳入一個字串時,輸出結果會以該字串作為縮排符號。
// 省略 person物件
// 使用 * 號縮排
var jsonText = JSON.stringify(person, null, "*");
console.log(jsonText);
// 輸出
{
*"name": "acwong",
*"age": 23,
*"address": {
**"province": "GuangDong",
**"city": "GuangZhou"
*},
*"friends": [
**"bc",
**"cc",
**"dc"
*],
*"blog": "http://acwong.org"
}
// 省略 person物件
// 使用製表符(Tab)縮排
var jsonText = JSON.stringify(person, null, " ");
console.log(jsonText);
// 輸出
{
"name": "acwong",
"age": 23,
"address": {
"province": "GuangDong",
"city": "GuangZhou"
},
"friends": [
"bc",
"cc",
"dc"
],
"blog": "http://acwong.org"
}
自定義序列化
如果上述的方法都不能滿足要求,還可以在要序列化的 JavaScript物件當中加入 toJSON()
函式,可以返回任何想返回的值。
var person = {
name: "acwong",
age: 23,
address: {
province: "GuangDong",
city: "GuangZhou"
},
friends: ["bc", "cc", "dc"],
blog: "http://acwong.org",
toJSON: function() {
this.name = "ac";
return "yoyo " + this.name;
}
};
var jsonText = JSON.stringify(person);
console.log(jsonText);
// "yoyo ac"
解析 JSON
JavaScript 使用 JSON物件的 parse()
方法來解析 JSON。
var jsonText = `{"name":"acwong","age":23,"address":{"province":"GuangDong","city":"GuangZhou"},"friends":["bc","cc","dc"],"blog":"http://acwong.org"}`;
var person = JSON.parse(jsonText);
console.log(person);
JSON.parse()
同樣可以傳入一個函式作為引數,對鍵值對進行操作。
var jsonText = `{"name":"acwong","age":23,"blog":"http://acwong.org"}`;
var person = JSON.parse(jsonText);
console.log(person);
JSON 的好處
-
與 XML 一樣可以表示複雜的資料結構。
-
比 XML 輕量得多。
-
語法簡單易懂。
-
由於其輕量級,在傳輸的時候佔用的資源相對較少。
感謝您的閱讀,有不足之處請為我指出。
參考
本文同步於我的個人部落格 http://blog.acwong.org/2015/03/05/json-notes/