JavaScript之JSON

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表示布爾值時,不能添加雙引用,否則就變成了字符串。


對象

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字符串中保留空格和縮進。


過濾結果

如果第二個參數是一個數組,那麼JSON.parse()的結果將只包含數組中列出的屬性
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:
  • 讀取JSON字符串
  • 使用eval()處理JSON字符


發佈了109 篇原創文章 · 獲贊 56 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章