JSON 是 JavaScript 的一個嚴格的子集,利用了 JavaScript中的一些模式來表示結構化數據。關於 JSON,最重要的是要理解它是一種數據格式,不是一種編程語言。雖然具有相同的語法形式,但
JSON 並不從屬於 JavaScript。
1.語法
JSON 的語法可以表示以下三種類型的值:
- 簡單值:使用與 JavaScript 相同的語法,可以在 JSON 中表示字符串、數值、布爾值和 null。但JSON不支持 JavaScript 中的特殊值 undefined。
- 對象:對象作爲一種複雜數據類型,表示的是一組無序的鍵值對。而每個鍵值對兒中的值可以是簡單值,也可以是複雜數據類型的值。
- 數組:數組也是一種複雜數據類型,表示一組有序的值的列表,可以通過數值索引來訪問其中的值。數組的值也可以是任意類型——簡單值、對象或數組。
JSON 不支持變量、函數或對象實例,它就是一種表示結構化數據的格式,雖然與 JavaScript 中表示數據的某些語法相同,但它並不侷限於 JavaScript 的範疇。
1.1簡單值
JavaScript 字符串與 JSON 字符串的最大區別在於, JSON 字符串必須使用雙引號(單引號會導致語法錯誤)。
1.2對象
與 JavaScript 的對象字面量相比, JSON 對象有兩個地方不一樣。首先,沒有聲明變量(JSON 中沒有變量的概念);其次,沒有末尾的分號;對象的屬性必須加雙引號。
(因爲這不是 JavaScript 語句,所以不需要分號)。
//JavaScript對象字面量:
var object = {
"name": "Nicholas",
"age": 29
};
//JSON 表示上述對象的方式如下:
{
"name": "Nicholas",
"age": 29
}
1.3數組
JSON 數組採用的就是 JavaScript 中的數組字面量形式。
//JavaScript 中的數組字面量:
var values = [25, "hi", true];
//在 JSON 中,可以採用同樣的語法表示同一個數組:
[25, "hi", true]
2.解析與序列化
可以把JSON 數據結構解析爲有用的 JavaScript 對象。
2.1JSON對象
JSON 對象有兩個方法: stringify()和 parse()。在最簡單的情況下,這兩個方法分別用於把JavaScript 對象序列化爲 JSON 字符串和把 JSON 字符串解析爲原生 JavaScript 值。
var book = {
title: "Professional JavaScript",
authors: [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};
var jsonText = JSON.stringify(book);
//{"title":"Professional JavaScript","authors":["Nicholas C. Zakas"],"edition":3,"year":2011}
var bookCopy = JSON.parse(jsonText);
如果傳給 JSON.parse()的字符串不是有效的 JSON,該方法會拋出錯誤。
2.2序列化選項
JSON.stringify()除了要序列化的 JavaScript 對象外,還可以接收另外兩個參數,這兩個參數用於指定以不同的方式序列化 JavaScript 對象。第一個參數是數據,第二個參數是個過濾器,可以是一個數組,也可以是一個函數;第三個參數是一個選項,表示是否在 JSON 字符串中保留縮進。
1.過濾結果
如果過濾器參數是數組,那麼 JSON.stringify()的結果中將只包含數組中列出的屬性。
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};
var jsonText = JSON.stringify(book, ["title", "edition"]);
//{"title":"Professional JavaScript","edition":3}
如果過濾器參數是函數,傳入的函數接收兩個參數,屬性(鍵)名和屬性值。
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};
var jsonText = JSON.stringify(book, function(key, value){
switch(key){
case "authors":
return value.join(",")
case "year":
return 5000;
case "edition":
return undefined;
default:
return value;
}
});
//{"title":"Professional JavaScript","authors":"Nicholas C. Zakas","year":5000}
2.字符串縮進
JSON.stringify()方法的第三個參數用於控制結果中的縮進和空白符。如果這個參數是一個數值,那它表示的是每個級別縮進的空格數。
如果縮進參數是一個字符串而非數值,則這個字符串將在 JSON 字符串中被用作縮進字符(不再使用空格)。在使用字符串的情況下,可以將縮進字符設置爲製表符,或者兩個短劃線之類的任意字符。
var jsonText = JSON.stringify(book, null, " - -");
這樣, jsonText 中的字符串將變成如下所示:
{
--"title": "Professional JavaScript",
--"authors": [
----"Nicholas C. Zakas"
--],
--"edition": 3,
--"year": 2011
}
縮進字符串最長不能超過 10 個字符長。如果字符串長度超過了 10 個,結果中將只出現前 10 個字
符。
3.toJSON()方法
給對象自定義toJSON()方法,返回其自身的JSON數據格式。
假設把一個對象傳入 JSON.stringify(),序列化該對象的順序如下:
(1) 如果存在 toJSON()方法而且能通過它取得有效的值,則調用該方法。否則,返回對象本身。
(2) 如果提供了第二個參數,應用這個函數過濾器。傳入函數過濾器的值是第(1)步返回的值。
(3) 對第(2)步返回的每個值進行相應的序列化。
(4) 如果提供了第三個參數,執行相應的格式化。
2.3解析選項
JSON.parse()方法也可以接收另一個參數,該參數是一個函數(還原函數),將在每個鍵值對兒上調用。
如果還原函數返回 undefined,則表示要從結果中刪除相應的鍵;如果返回其他值,則將該值插入到結果中。在將日期字符串轉換爲 Date 對象時,經常要用到還原函數:
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011,
releaseDate: new Date(2011, 11, 1)
};
var jsonText = JSON.stringify(book);
var bookCopy = JSON.parse(jsonText, function(key, value){
if (key == "releaseDate"){
return new Date(value);
} else {
return value;
}
});
alert(bookCopy.releaseDate.getFullYear());
3.小結
JSON 是一個輕量級的數據格式,可以簡化表示複雜數據結構的工作量。JSON 使用 JavaScript 語法的子集表示對象、數組、字符串、數值、布爾值和 null。即使 XML 也能表示同樣複雜的數據結果,但JSON 沒有那麼煩瑣,而且在 JavaScript 中使用更便利。
ECMAScript 5 定義了一個原生的 JSON 對象,可以用來將對象序列化爲 JSON 字符串或者將 JSON數據解析爲 JavaScript 對象。 JSON.stringify()和 JSON.parse()方法分別用來實現上述兩項功能。
這兩個方法都有一些選項,通過它們可以改變過濾的方式,或者改變序列化的過程。原生的 JSON 對象也得到了很多瀏覽器的支持,比如 IE8+、 Firefox 3.5+、 Safari 4+、 Opera 10.5 和Chrome。