語法
JSON可以表示一下三種型別的值:
-
簡單值:使用與js相同的語法可以在json中表示字串、數值、布林值和null。但是json不支援js的undefined。
-
物件:物件作為一種複雜的資料型別,表示的是一組有序的鍵值對。每個鍵值對的值可以是簡單值,也可以是複雜資料型別的值
-
陣列:陣列也是一種複雜資料型別,表示一組有有序的的值列表,可以通過數值索引來訪問其中的值。陣列的值也可以是任意型別,簡單值,物件,陣列均可。
json不支援變數,函式,物件例項,它就是一種表示結構化資料的格式。
簡單值
js字串與json最大的區別在於json字串必須使用雙引號,單引號會導致語法錯誤。
物件
js中的物件:
var person = {
name: "oliver",
age:29
};
但在JSON中屬性需要加上雙引號:
{
"name": "oliver",
"age": 29
}
並且沒有宣告變數;沒有末尾的分號。絕對不能在同一個物件中出現兩個同名屬性。
陣列
js中的陣列:
var values = [321,"Oliver",false]
JSON中的陣列:
[321,"Oliver",false]
JSON中沒有變數和分號。
解析與序列化
JSON物件
json流行的最主要的原因是因為json資料結構可以解析為js的物件。早期的json解析器基本上是使用js的eval()函式。對於較早版本的瀏覽器,可以使用一個shim:https://github.com/douglacrockford/JSON-js。對於那些不能原生支援JSON解析的瀏覽器,使用shim是最佳選擇。ECMAScript 5對解析JSON的行為進行了規範,定義了全域性物件JSON。
JSON物件有兩個方法:
-
stringify()
-
parse()
在最簡單的情況下,這兩個方法分別用於把javascript物件序列化為JSON字串和把JSON字串解析為原聲的javascript值。
如(JSON.stringify()):
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
other: undefined //被忽略
};
var jsontext = JSON.stringify(book);
console.log(jsontext); //{"title":"javascript","authors":["oliver","troy"],"edition":2,"year":2000}
又如(JSON.parse()):
var anotherBook = JSON.parse(jsontext);
console.log(Object.keys(anotherBook).toString()); //title,authors,edition,year
序列化選項
JSON.stringify()
除了要序列化的Javascript物件外,還可以接收另外兩個引數,這兩個引數用於指定以不同方式序列化javascript物件。
第一個引數是一個過濾器,可以是一個陣列,也可以是一個函式。
第二個引數是一個選項,表示是否在JSON字串中保留縮排。單獨或組合使用這兩個引數,可以全面化的控制JSON序列化。
過濾結果
當JSON.stringify()
的第二個引數是一個陣列。在返回結果中,只會包含這些屬性。
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
other: undefined //被忽略
};
var jsontext = JSON.stringify(book,["title","authors"]);
console.log(jsontext); //{"title":"javascript","authors":["oliver","troy"]}
如果第二個引數是函式,傳入的函式接收兩個引數,屬性名和屬性值(function (key,value))。
根據屬性名可以知道應該如何處理序列化的物件中的屬性。屬性名只能是字串,而在值並非鍵值對結構的值時,鍵名可以是空字串。為了改變序列化物件的結果,函式返回值就是相應鍵的值。如果返回undefined作為屬性值,則表示跳過這個屬性。
如:
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
other: undefined //被忽略
};
var jsontext = JSON.stringify(book,function (key,value) {
switch (key) {
case "authors":
return value.join("-");
break;
case "edition":
return undefined;
break;
default:
return value;
}
});
console.log(jsontext); //{"title":"javascript","authors":"oliver-troy","year":2000}
字串縮排
當JSON.stringify()的第三個引數是用於控制結果中的縮排和空白符。如果這個引數是一個數值,表示是每個級別縮排的空格數。
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
other: undefined //被忽略
};
var jsonText = JSON.stringify(book,null,4);
var pre = document.getElementById("pre");
pre.innerHTML = jsonText;
// {
// "title": "javascript",
// "authors": [
// "oliver",
// "troy"
// ],
// "edition": 2,
// "year": 2000
// }
最大的縮排空格數是10,超過10,則設定為10.
如果縮排字串是一個字串而非數值,則在這個字串將在JSON字串中被用作縮排字元。縮排字串最多也只出現10個字元長度。
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
other: undefined //被忽略
};
var jsonText = JSON.stringify(book,null,"----");
var pre = document.getElementById("pre");
pre.innerHTML = jsonText;
// {
// ----"title": "javascript",
// ----"authors": [
// --------"oliver",
// --------"troy"
// ----],
// ----"edition": 2,
// ----"year": 2000
// }
toJSON()
方法
toJSON()方法,為任何物件新增,它會在物件被序列化是呼叫,返回指定的資料,而不是整個物件的序列化資料。
toJSON()方法可以作為函式過濾器的補充,因此理解序列化內部順序十分重要。假設把一個物件傳入JSON.stringify(),序列化該物件的順序如下:
-
如果存在toJSON()方法而且能通過它取得有效地值,則呼叫該方法。否則按照預設順序執行序列化。
-
如果提供了第二個引數,應用這個函式過濾器。傳入函式過濾器的值是第一步的返回值。
-
對第2步返回的每個值進行相應的序列化
-
如果提供了第三個引數,執行相應的格式化
如:
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
toJSON: function () {
return this.title + this.edition; //javascript2
},
other: undefined //被忽略
};
var jsonText = JSON.stringify(book);
console.log(jsonText); //javascript2
解析選項
JSON.parse()
方法也可以接收另一個引數,該引數是一個函式,將在每個鍵值對上呼叫。
這個函式被稱為還原函式,它與JSON.stringify()方法中的過濾函式有些相似,都接收鍵值對,返回一個值。如果還原函式返回undefined,則表示要從結果中刪除相應的鍵,如果返回其他值,則將改值插入到結果中。
var book = {
title: "javascript",
authors: ["oliver", "troy"],
edition: 2,
year: 2000,
date: new Date(2001, 1, 1),
other: undefined //被忽略
};
var jsonText = JSON.stringify(book);
console.log(jsonText); //{"title":"javascript","authors":["oliver","troy"],"edition":2,"year":2000,"date":"2001-01-31T16:00:00.000Z"}
var anotherbook = JSON.parse(jsonText, function(key, value) {
switch (key) {
case "date":
return new Date(value);
break;
default:
return value;
break;
}
})