## JSON
JSON(JavaScript Object Notation,JavaScript對象表示法),它是JavaScript的一個嚴格子集。
JSON只是一種簡單數據格式,并不是只有JavaScript擁有。
**1、語法**
JSON對值的類型和格式有嚴格的規定:
- 復合類型的值只能是數組或對象,不能是函數、正則表達式對象、日期對象。
- 簡單類型的值只有四種:字符串、數值(必須以十進制表示)、布爾值和null(不能使用NaN, Infinity, -Infinity和undefined)。
- 字符串必須使用雙引號表示,不能使用單引號。
- 對象的鍵名必須放在雙引號里面。
- 數組或對象最后一個成員的后面,不能加逗號。
**1.1 簡單值**
最簡單的JSON數據形式就是簡單值。
```
5
"tg"
null
true
false
```
上面的都是有效的JSON數據。
**1.2 對象**
JSON中的對象與JavaScript中的對象字面量基本一樣,除了JSON中的對象要求對象的屬性一定要加上雙引號(對象字面量的屬性對引號可有可無)。
```
{
name: "tg"
}
{
'name': "tg"
}
```
上面兩個對象對于JSON來說是錯誤的,正確的寫法如下:
```
{
"name": "tg"
}
```
當然,你可以使用嵌套對象:
```
{
"name": "tg",
"school": {
"name": "tg",
"location": "gz"
}
}
```
可能你注意到了,上面有兩個同名(name)屬性,這是沒問題的,因為它們屬于不同的對象,但是請注意,同一對象內不能出現兩個同名屬性。
**1.3 數組**
JSON數組采用的是JavaScript中的數組字面量。
```
{
"color": ["red","blue"]
}
```
當然,你也可以在數組中放對象,對象中放數組。
**2、 解析與序列化**
JSON在JavaScript中流行的原因是JSON數據結構可以解析成有用的JavaScript對象。
**2.1序列化和反序列化**
JSON對象有兩個方法:`JSON.stingify()`和`JSON.parse()`,分別表示將JavaScript對象序列化為JSON字符串和把JSON字符串解析為原生的JavaScript值。
**2.1.1 JSON.stringify()**
**(1)基本用法**
`JSON.stringify`方法用于將一個Javascript對象序列化為字符串。該字符串應該符合JSON格式,并且可以被`JSON.parse`方法還原。
注意:在序列化JavaScript對象時,所有函數及原型成員都會被有意忽略,不體現在結果中,而且值為undefined的任何屬性也會被跳過,還有正則對象會被轉成空對象。,最終返回來的值為有效的JSON格式。
```
var data = {
name: 'tg',
age: 1,
books: [ "Javascript", 2],
location:{
name: "gz",
},
test: function(){},
sex: undefined
};
console.log(JSON.stringify(data));
//{"name":"tg","age":1,"books":["Javascript",2],"location":{"name":"gz"}}
```
在上面的例子中,將data對象轉換成JSON字符串,我們可以看到,鍵名都被雙引號括起來了,而對于原始類型的字符串(name: 'tg'),也由單引號轉成了雙引號,這是因為將來還原的時候,雙引號可以讓JavaScript引擎知道,tg是一個字符串,而不是一個變量名。而且test和sex并沒有在返回值中,這是因為test是函數,而sex的值是undefined。
**(2)過濾結果**
`JSON.stringify()`還可以接受第二個參數,指定需要轉成字符串的屬性。
當傳入的參數是`數組`時,那么JSON.stringify()的結果中將只包含數組中列出的屬性。
例子:
```
var data = {
name: 'tg',
age: 1,
books: [ "Javascript", 2],
location:{
name: "gz",
},
test: function(){},
sex: undefined
};
console.log(JSON.stringify(data,["name","books"]));
//{"name":"tg","books":["Javascript",2]}
```
在上面的例子中,傳給JSON.stringify()的第二個參數是一個數組,其中包含兩個字符串:“name”和“books”,這兩個屬性與將要序列化的對象中的屬性是對應的,因此在返回的結果字符串中,就只會包含這兩個屬性(如上結果)。
第二個參數還可以是函數,它接收兩個參數:屬性(鍵)名和屬性值,返回的值就是相應鍵的值(它改變了序列化對象的結果)。
屬性名只能是字符串,而在值并非鍵值對的值時,鍵名可以是空字符串。
```
var jsonText = JSON.stringify(data,function(key, value){
if(key == 'books'){
return value.join(',');
}else{
return value;
}
});
console.log(jsonText);
//{"name":"tg","age":1,"books":"Javascript,2","location":{"name":"gz"}}
```
在上面的例子中,如果鍵名為"books",就將數組連成一個字符串,否則,返回原值。
注意:如果函數返回了undefined,那么相應的屬性會被忽略。
**(3)字符串縮進**
JSON.stringify()方法還可以接收第三個參數,用于控制結果中的縮進和空白符。如果這個參數是數值,那它表示的是每個級別縮進的空格數。比如,要在每個級別縮進4個空格:
```
var data = {
name: 'tg',
age: 1,
books: [ "Javascript", 2],
location:{
name: "gz",
},
test: function(){},
sex: undefined
};
console.log(JSON.stringify(data, null, 4));
// 結果
{
"name": "tg",
"age": 1,
"books": [
"Javascript",
2
],
"location": {
"name": "gz"
}
}
```
當傳入有效的控制縮進的參數值時,結果字符串就會自動包含換行符。不過要注意:最大縮進空格數為10,所有大于10的值都會自動轉換為10.
如果縮進參數是一個字符串而非數值,則這個字符串將在JSON字符串中被用作縮進字符。
例子:
```
var data = {
name: 'tg',
age: 1,
books: [ "Javascript", 2],
location:{
name: "gz",
},
test: function(){},
sex: undefined
};
console.log(JSON.stringify(data, null, 4));
// 結果
{
--"name": "tg",
--"age": 1,
--"books": [
----"Javascript",
----2
--],
--"location": {
----"name": "gz"
--}
}
```
注意:縮進字符串最長不能超過10個字符長,如果超過了10個,結果中只會顯示10個字符。
**(4)toJSON()方法**
如果JSON.stringify的參數對象有自定義的toJSON方法,那么JSON.stringify會使用這個方法的返回值作為參數,而忽略原對象的其他屬性。
```
var data = {
name: 'tg',
age: 1,
toJSON:function(){
var data = {
name: this.name
};
return data;
}
};
console.log(JSON.stringify(data));
//{"name":"tg"}
```
在上面的代碼中,我們給data對象定義了一個toJSON()方法,該方法返回name的值。
可以讓toJSON()方法返回任何序列化的值。
假設將一個對象傳入JSON.stringify(),序列化對象的順序如下:
- 如果存在toJSON()方法而且能通過它取得有效的值,則調用該方法,否則,按默認順序序列化。
- 如果提供了第二個參數,應用這個函數過濾器。傳入函數過濾器的值是第(1)步返回的值
- 對第(2)步返回的每個值進行相應的序列化
- 如果提供了第三個參數,執行相應的格式化
**2.1.2 JSON.parse()**
`JSON.parse`方法用于將JSON字符串轉化成原生的JavaScript對象。
例子:
```
var jsonText = '{"name":"tg","age":1,"books":["Javascript",2],"location":{"name":"gz"}}';
console.log(JSON.parse(jsonText));
//返回對象
{
name: 'tg',
age: 1,
books: [ "Javascript", 2],
location:{
name: "gz",
}
};
```
如果傳入的字符串不是有效的JSON格式,則會報錯。
JSON.parse()也可以接收另一個參數,該參數是一個函數,將在每個鍵值對上調用。
例子:
```
var jsonText = '{"name":"tg","age":1,"books":["Javascript",2],"location":{"name":"gz"}};
var o =JSON.parse(jsonText,function(key, value){
if(key == "name"){
return "Hello";
}
return value;
});
console.log(o.name);
// Hello
```
在上面的例子中,在解析時,當遇到鍵名是“name”時,就將相應的值替換成"Hello",最終返回的name就是"Hello"。
如果函數返回undefined,則表示要從結果中刪除相應的鍵,如果返回其他值,則將其放入到結果中。
- 前言
- JavaScript簡介
- 基本概念
- 語法
- 數據類型
- 運算符
- 表達式
- 語句
- 對象
- 數組
- 函數
- 引用類型(對象)
- Object對象
- Array對象
- Date對象
- RegExp對象
- 基本包裝類型(Boolean、Number、String)
- 單體內置對象(Global、Math)
- console對象
- DOM
- DOM-屬性和CSS
- BOM
- Event 事件
- 正則表達式
- JSON
- AJAX
- 表單和富文本編輯器
- 表單
- 富文本編輯器
- canvas
- 離線應用
- 客戶端存儲(Cookie、Storage、IndexedDB)
- HTML5 API
- Video/Audio
- Geolocation API
- requestAnimationFrame
- File API
- FullScreen API
- IndexedDB
- 檢測設備方向
- Blob
- vibrate
- Luminosity API
- WebRTC
- Page Visibility API
- Performance API
- Web Speech
- Notification
- 面向對象的程序設計
- 概述
- this關鍵字
- 原型鏈
- 作用域
- 常用API合集
- SVG
- 錯誤處理機制
- JavaScript開發技巧合集
- 編程風格
- 垃圾回收機制