JSON
- 一、語法
- 1、簡單值
- 2、物件
- 3、陣列
- 二、決議與序列化
- 1、JSON物件
- 1、stringify()方法
- 2、parse()方法
- 2、序列化選擇
- 1、過濾結果
- 2、字串縮進
- 3、toJSON()方法
- 3、決議選項
JSON:( JavaScript Object Notation JavaScript 物件標記法) 是一種存盤和交換資料的語法,JSON 是通過 JavaScript 物件標記法書寫的文本,它是一種資料格式,不是一種編程語言,雖然具有相同的語法形式,但JSON從不屬于JavaScript,而且,并不是只有JavaScript才使用JSON,畢竟JSON只是一種資料格式,很多編程語言都有針對JSON的決議器和序列化器,
一、語法
JSON的語法可以表示以下三種型別的值,
- 簡單值:使用與JavaScript相同的語法,可以在JSON中表示字串、數值、布林值和null.
- 物件:物件作為一種復雜資料型別,表示的是一組無序的鍵值對,而每個鍵值對中的值可以是簡單值,也可以是復雜資料型別的值
- 陣列:陣列也是一種復雜資料型別,表示一組有序的值的串列,可以通過陣列索引來訪問其中的值,陣列的值也可以是任意型別——簡單值、物件或陣列,
JSON不支持變數、函式或物件實體,它就是一種表示結構化資料的格式,
1、簡單值
5
這就是JSON表示數值5的方式,
"Hello world!"
這是JSON表示字串的方式,JavaScript字串和JSON字串最大的區別在于:JSON字串必須使用雙引號(單引號會導致語法錯誤),
2、物件
JSON中的物件和JavaScript字面量稍微有一些不同,例如:
var person = {
name: '投訓',
age: 18
};
上述是一個JavaScript中創建字面量的方式,實際上,在JS中,這個物件字面量完全可以寫成:
var person = {
"name": '投訓',
"age": 18
};
但是,在JSON中,表示上述物件的方式為:
{
"name": '投訓',
"age": 18
};
在這里,JSON有兩點與JavaScript不同,首先,沒有宣告變數(JSON中沒有變數的概念);其次,沒有末尾的分號,而且,需要注意的是:在JSON中,物件的屬性必須加雙引號,屬性的值可以是簡單值,也可以是復雜型別值,
比如:可以用JSON實作物件中嵌套物件
{
"name": "投訓".
"age":18,
"college": {
"name": "西安郵電大學",
"location": "xi'an"
}
上面這個例子在頂級物件中嵌套了學校(“college”)的資訊,雖然,在上面的例子中,有兩個name屬性,但由于他們分別屬于不同的物件,所以可以這樣寫,不過,同一個物件中絕對不應該出現兩個同名屬性,
3、陣列
JSON的第二種復雜資料型別是陣列,JSON陣列采用的就是JavaScript中的陣列字面量形式,
如下是JavaScript的陣列字面量:
var values = [25,"hello",true];
在JSON中,可以采用同樣的語法表示同一個陣列:
[25,"hello",true]
還可以把陣列和物件結合起來,構成更復雜的資料集合,例如:
[
{
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100
},{
"college": "西北政法大學",
"name": "王寧",
"sex": "女",
"score": 98
},{
"college": "陜西師范大學",
"name": "小熊",
"sex": "女",
"score": 95
},{
"college": "西安交通大學",
"name": "小明",
"sex": "男",
"score": 99
}
]
這個陣列包含一些表示學校學生的物件,每個物件都有幾個屬性,物件和屬性通常是JSON資料結構的最外層形式,利用他們可以創造出各種各樣的資料結構,
二、決議與序列化
JSON之所以流行,一方面是因為其擁有與JavaScript類似的語法,更重要的一方面是因為可以把JSON資料結構決議為有用的JavaScript物件,
以上例一組包含學校的JSON資料結構為例,在決議為JavaScript物件后,將其保存到變數message中,只需要很簡單的操作就可以獲取西安郵電大學的學生:
message[0].name
但是如果在DOM中查找的話,代碼就是:
doc.getElementsByTagName("message")[0].getAttrbute("name")
孰更簡單,一目了然,所以就不難理解為什么JSON越來越被歡迎了,我們就具體來看一下 :
1、JSON物件
JSON有兩種方法:stringify()和parse(),在簡單的情況下,這兩個方法分別用于吧JavaScript物件序列化為JSON字串和把JSON字串決議為原生JavaScript值,
1、stringify()方法
例如:
var message = {
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100
};
var mes = JSON.stringify(message);
這個例子用JSON.stringify()把一個JavaScript物件序列化為一個JSON字串,然后將它保存在mes中,默認情況下,JSON.stringify()輸出的JSON字串不包含任何空格字符或縮進,因此保存在mes中的字串如下所示:
{"college": "西安郵電大學","name": "投訓","sex": "女","score": 100}
我們來列印一下試試:

在序列化JavaScript物件時,所有函式即原型成員都會被有意忽略,不體現在結果中,此外,值為undefined的任何屬性也都會被跳過,結果最終都是值為有效JSON資料型別的實體屬性,
2、parse()方法
將JSON字串直接傳遞給JSON.parse()就可以得到相應的JavaScript值,例如:下述代碼就可以創建于mes類似的物件:
var mesCopy = JSON.parse(mes);
列印一下nameCopy可以看到:該JSON字串被決議成了原生JavaScript值,

注意:雖然mes和mesCopy具有相同的屬性,但它們兩個是相互獨立的、沒有任何關系的物件,
如果傳給JSON.parse()的字串不是有效的JSON,該方法會拋出錯誤,
2、序列化選擇
實際上,JSON.stringify()除了要序列化的JavaScript物件外,還可以接收另外兩個引數,這兩個引數用于指定不同的方式序列化JavaScript物件,第一個引數是個過濾器,可以是一個陣列,也可以是一個函式,第二個引數是一個選項,表示是否在JSON字串中保留縮進,單獨或組合使用這兩個引數,可以更全面深入的控制JSON序列化,
1、過濾結果
如果過濾器引數是陣列,那么JSON.stringify()的結果中將只包含陣列,中列出的屬性,如下例:
var message = {
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100
};
var mes = JSON.stringify(message,["college","name"]);
JSON.stringify()的第二個引數是一個陣列,其中包含兩個字串:"college"和"name",這兩個屬性與將要序列化的物件中的屬性是對應的,因此在回傳的結果字串中,就會只包含這兩個屬性,我們來列印看看:

如果第二個引數是函式,行為會稍有不同,傳入的函式接收兩個引數,屬性(鍵)名和屬性值,根據屬性(鍵)名可以知道應該如何處理要序列化的物件中的屬性,屬性名只能是字串,而在值并非鍵值對結構的值時,鍵名可以是空字串,為了改變序列化物件的結果,函式回傳的值就是相應鍵的值,不過要注意,如果函式回傳了undefined,那么相應的屬性會被忽略,舉例說明:
var message = {
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100,
};
var mes = JSON.stringify(message,function(key,value){
switch(key){
case "name":
return value;
case "score":
return undefined;
default:
return value;
}
});
console.log(mes);
如果鍵為"name",回傳其值,如果鍵為"score",通過回傳undefined洗掉該屬性,在最后,一定要提供default項,此時回傳傳入的值,以便其他值都能正常出現在結果中,
列印結果為:

要序列化的物件中的每一個物件都要經過過濾器,因此陣列中的每個帶有這些屬性的物件經過過濾之后,每個物件都只會包含"college"、"name"和"sex"屬性,
2、字串縮進
JSON.stringify()方法的第三個引數用于控制結果中的縮進和空白符,如果這個引數是一個數值,那它表示的是每個級別縮進的空格數,
例如:要在每個級別縮進4個空格,可以這樣寫:
var message = {
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100,
};
var mes = JSON.stringify(message,null,4);
再來列印一下結果看看:

可以發現的是:JSON.stringify()也在結果字串中插入了換行符以提高可讀性,只要傳入有效的控制縮進的引數值,結果字串就會包含換行符,最大縮進空格數為10,所有大于10的值都會自動轉換為10,
如果縮進引數是一個字串而非數值,則這個字串將JSON字串中被用作縮進字符(不在使用空格),在使用字串的情況下,可以將縮進字符設定為制表符,或者兩個短劃線之類的任意字符,
var mes = JSON.stringify(message,null,"--");
這樣,mes中的字符將變成如下所示:

需要注意的是:縮進字串最長不能超過10個字符長,如果字串長度超過了10個,結果將只出現前十個字符,
3、toJSON()方法
但是,JSON.stringify()有時候還是不能滿足對某些物件進行自定義序列的需求,在這些情況下,可以給物件定義toJSON()方法,回傳其自身的JSON資料格式,
可以為任何物件添加toJSON()方法,比如:
var message = {
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100,
toJSON:function(){
return this.college;
}
};
var mes = JSON.stringify(message);
以上代碼在message物件上定義了一個toJSON()方法,該方法回傳具體學校的學生姓名,toJSON()可以作為函式過濾器的補充,因此理解序列化的內部順序十分重要,
假設把一個物件傳入JSON.stringify(),序列化該物件的順序如下:
- 如果存在
toJSON()方法并且能夠取到有效的值,則呼叫該方法,否則,回傳物件本身, - 如果提供了第二個引數,應用這個函式過濾器,傳入函式過濾器的值是第一步回傳的值,
- 對第二步回傳的每個值進行相應的序列化,
- 如果提供了第三個引數,執行相應的格式化,
3、決議選項
JSON.parse()方法也可以接收另一個引數,該引數是一個函式,將在每個鍵值對上呼叫,為了區別JSON.stringify()接收的替換函式(replacer),這個函式被被稱為還原函式(reviver),但實際上這兩個函式的簽名是相同的——他們都接受兩個引數,一個鍵和一個值,而且都需要回傳一個值,
如果還原函式回傳undefined,則表示要從結果中洗掉相應的鍵;如果回傳其他值,則將該值插入到結果中,
將日期字串轉換成Date物件時,經常要用到還原函式,例如:
var message = {
"college": "西安郵電大學",
"name": "投訓",
"sex": "女",
"score": 100,
releaseDate: new Date(2021,12,7)
};
var mes = JSON.stringify(message);
var mesCopy = JSON.parse(mes,function(key,value){
if(key == "releaseDate"){
return new Date(value);
}else{
return value;
}
});
console.log(mesCopy.releaseDate.getFullYear());
列印結果為:

以上代碼先是為message物件新增了一個releaseDate屬性,該屬性保存著一個Date物件,這個物件在經過序列化后變成了有效的JSON字串,然后經過決議又在mesCopy中還原為一個Date物件,還原函式在遇到releaseDate鍵時,會基于相應的值創建一個新的Date物件,結果就是mesCopy.releaseDate屬性會保存一個Date物件,正因為如此,才能基于這個物件呼叫getFullYear()方法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/377106.html
標籤:其他
上一篇:[移動端]視口與媒體查詢
