JSON是JavaScript一個嚴格的子集,它利用了JavaScript中的模式表示結構化數據。JSON可以直接傳給eval(),而不必創建DOM對象(不必聲明變量)。
注:JSON是一種數據格式,不是編程語言。JSON不是JavaScript獨有的。
什麼是JSON:
- JSON是JavaScript對象表示法
- JSON是輕量級的文本數據交換格式
- JSON具有獨立性,不是JavaScript獨有的。
- JSON具有自我供述性、更容易理解。
語法
JSON的語法可以表示以下三種類型的值:
- 簡單值,與JavaScript語法相似,可以表示數字值、字符串值、布爾值和null,但JSON不能表示undefined。
- 對象,與JavaScript中的對象相似。
- 數組,與JavaScript中的數組相似。
注:JSON不支持變量,函數或對象實例,它只是一種表示結構化數據的格式。因此,JSON沒有聲明變量一說,三種類型的值直接書寫就是。
簡單值
JSON支持數字值、字符串、布爾值和null。
在JavaScript中表示這三種類型的值可以是這樣的:
var a = 1234, //表示數字值
b = "hello JSON", //表示字符串,用雙引號
c = "hello JavaScript", //表示字符串,用單引號
d = true; //表示布爾值
而在JSON是這樣表示這三種類型的值的:
1234
"hello JSON"
"hello JavaScript"
true
從上述兩個例子,我們可以看出JavaScript與JSON的兩個不同點:
- JavaScript需要聲明變量用來保存這三種類型的值,也就是說需要聲明變量並初始化變量,且每個語句後面必須有分號表示。而JSON因爲不支持變量,所以無需聲明變量,直接書寫值,並傳遞給eval(),並且JSON不加分號。
- JavaScript字符串與JSON字符串的最大區別在於,JavaScript的字符串可以用雙引號表示,也可以用單引號表示。但JSON的字符串必須用雙引號表示,否則會報錯。
對象
JSON的對象與JavaScript字面量對象有一點不同,在JavaScript中表示字面量對象:
var obj = {
name : "tom",
age : 21,
sayName : function () {
alert(this.name);
}
};
在JavaScript中,屬性名也可以添加雙引用表示:
var obj = {
“name” : "tom",
“age” : 21,
“sayName” : function () {
alert(this.name);
}
};
而在JSON中,沒有聲明變量這一操作(不支持變量),屬性名必須用雙引用,且末尾沒有分號,注:花括號是有的
{
"name" : "tom",
"age" : 21,
"sayName" : function () {
alert(this.name);
}
}
再次聲明:JSON對象或字符串中,屬性名或字符串必須添加雙引用。
數組
JSON數組就是採用JavaScript的字面量形式,在JavaScript中的字面量數組:
var arr = [21, "tom", true];
而在JSON中的字面量數組:
[21, "tom", true]
可以看出,JSON中的字面量數組,沒有聲明變量這一操作,且末尾沒有分號。
解析與序列化
JSON可以把JSON數據結構解析爲JavaScript對象。
JSON對象
JSON對象有兩個方法,分別是stringify()和parse()。在最簡單的情況下,它們分別可以將JavaScript對象序列化爲JSON字符串和將JSON字符串解析成JavaScript值。
例如:
var book = {
title : "a good book",
authors : "zhang",
edition : 3,
year : 2017
};
//將JavaScript對象序列化爲JSON字符串,並將其保存在變量jsonText中
var jsonText = JSON.stringify(book);
JSON.stringify()將JavaScript對象序列化爲JSON字符串,默認情況下(在沒有傳入參數的情況下),輸出的JSON字符串不包含任何空格和縮進,此時輸出的JSON字符串爲:
{"title":"a good book","authors":"zhang","edition":3,"year":2017}
除了原字符串間的空格,其它的空格和縮進均被刪除了。
注:在序列化JavaScript對象時,所有的函數和原型成員會被有意忽略。值爲undefined的任何屬性也會被跳過。
將JSON字符串傳遞給JSON.parse()會得到相應的JavaScript值。
var javaScriptText = JSON.parse(jsonText);
注:book與javaScriptText雖然有相同的屬性,但它們是相互獨立、沒有任何關係的對象。如果傳遞給JSON.parse()的不是有效的JSON字符,則會報錯。
序列化選項
JSON.parse()方法可以接收三個參數:第一個參數就是要序列化的JavaScript對象,第二個參數是個過濾器,可以是一個數組,也可以是一個函數,第三個參數是個選項,表示是否在JSON字符串中保留空格和縮進。
過濾結果
var book = {
title : "a good book",
authors : "zhang",
edition : 3,
year : 2017
};
//數組中列出的屬性是title、year,那麼JSON字符串中只保留這兩個屬性及屬性值。
var jsonText = JSON.stringify(book, ["title", "year"]);
JSON.parse()輸出的結果爲:
{"title":"a good book","year":2017}
結果中只保留了"title"和"year"這兩個屬性。
如果第二個參數是一個函數,那麼此函數接收兩個參數:屬性名和屬性值,根據屬性名可以知道如何處理要序列化的對象中的屬性。
JSON字符串縮進
JSON.stringify*()方法中的第三個參數用於控制結果中的空格和縮進。
如果是參數數值,注:最大縮進數爲10,如果設置的縮進數大於10,則轉換成10。
var book = {
title : "a good book",
authors : "zhang",
edition : 3,
year : 2017
};
//結果中以4爲縮進數
var jsonText = JSON.stringify(book, [book, null, 4]);
輸出結果:
{
title : "a good book",
authors : "zhang",
edition : 3,
year : 2017
}
字符間的縮進數爲4,當設置有效的縮進參數時,那麼結果中也會包含換行符,如果只有縮進而無換行,那麼縮進也沒有多大意義。
當第三個參數(縮進參數)不是數字,而是其它字符時,那麼就以此字符中縮進,如:
var book = {
title : "a good book",
authors : "zhang",
edition : 3,
year : 2017
};
//結果中以"--"爲縮進數
var jsonText = JSON.stringify(book, [book, null, "--"]);
輸出結果:
{
--title : "a good book",
--authors : "zhang",
--edition : 3,
--year : 2017
}
"--"代替了縮進空格。至於換行,則是因爲有效的縮進"--"的結果。
注:同理,當以字符爲縮進參數時,字符的長度也不能超過10個字符,如果超過10個字符,那麼只顯示前10個字符。
toJSON()方法
toJSON()方法返回自身的JSON數據格式。如果對象中有這個方法,則優先執行該方法,且能通過它取得有效值的話,返回該方法的值。執行完這個方法後,纔開始序列化對象。
可以爲任何對象添加toJSON()方法:
var book = {
title : "a good book",
authors : "zhang",
edition : 3,
year : 2017
toJSON : function () {
return this.title;
}
};
var jsonText = JSON.stringify(book, [book]);
此對象定義了一個toJSON()方法,返回"title"的值。那麼這個對象將被序列化爲一個字符串而非對象了。可以讓toJSON()方法返回任何值,它才能正常工作。
理解序列化的內部順序:
- 如果對象中有toJSON()方法,且通過它能取得有效的值,則調用該方法,否則返回對象本身。
- 如果提供了第二個參數,應用這個函數過濾器,傳入過濾器的值是上一步返回的值。
- 將上一步返回的每個值序列化。
- 如果有第三參數,則進行相應的格式化。
解析選項
JSON.parse()方法接收兩個參數:第一個參數是JSON字符串,第二個參數是一個還原函數,與JSON.stringify()方法的過濾器的簽名是相同的--接收兩個參數,即屬性名和屬性值。
總結
JSON的特點:
- JSON是純文本
- JSON具有層次結構(值中有值)
- JSON可通過JavaScript的eval()解析
- JSON可被Ajax傳輸
- JSON具有自我描述性
JSON與XML的不同之處:
- 沒有結束標籤
- 更短
- 讀寫速度更快
- 可被JavaScript的eval()解析
- 使用數組
- 不使用保留字
爲什麼JSON比XML的讀寫速度更快:
使用XML:
- 讀取XML文檔
- 使用XML DOM來循環遍歷文檔
- 讀取值並保存在變量中
- 讀取JSON字符串
- 使用eval()處理JSON字符