JSON只是一種字符串數據花樣,運用它的不僅僅是Javascript。
語法
JSON能夠示意三種範例的值:簡樸值、對象、數組
簡樸值
以下是JSON能夠辨識的簡樸值例子:
5
"Hello World!"
false
null
*注重:
- undefined不被支撐
- 字符串必需運用雙引號,單引號會致使語法錯誤
對象
在Javascript中,我們能夠用對象字面量的體式格局建立一個對象:
var person = {
name: "Sue",
age: "18"
}
但JSON請求給屬性加雙引號,上述對象轉換成正當的JSON字符串花樣:
{
"name": "Sue",
"age": "18"
}
*注重:
- 屬性加雙引號
- 沒有變量聲明
- 沒有末端分號
- 屬性的值能夠是前面引見的簡樸值,也能夠是對象或數組
- 2、3點一樣適用於簡樸值和數組
數組
在Javascript中,我們能夠建立一個以下數組:
var names = ["Sue", "Jane", "Ben"]
上述數組轉換成正當的JSON字符串花樣:
["Sue", "Jane", "Ben"]
我們能夠將數組、簡樸值、對象嵌套運用,建立越發龐雜的JSON字符串,比方:
{
"teachers": [
{ "name": "Sue", "age": 18, "students": [1, 45, 60]},
{ "name": "Ben", "age": 25, "students": [2, 31, 40]}
],
"students": [
{ "id": 1, "name": "Jane"},
{ "id": 2, "name": "Lee"}
]
}
剖析與序列化
在JSON之前,web傳輸花樣化數據都是運用XML,Javascript要想拿到XML中的數據,要先將其轉換成DOM,然後從中提取數據,相比之下,JSON就顯得異常簡樸。
eval
初期剖析JSON平常運用eval()
,比方:
eval({"name": "Sue"})
{name: "Sue"}
但這類體式格局存在風險,由於服務器返回的數據很有能夠存在惡意代碼,只需被剖析成正當的Javascript語法,就會被執行,比方:
eval("alert('Sue')")
因而不發起運用eval()
來剖析JSON字符串。
初期瀏覽器中,能夠運用https://github.com/douglascro…。
JSON對象
在IE 8+、 Firefox 3.5+、 Safari 4+、 Chrome、Opera 10.5+中,ECMAScript定義了全局對象JSON。
stringify
用於把Javascript對象序列化為JSON字符串。
*注重:
- 值為
undefined
的屬性會被疏忽 - 函數及原型成員會被疏忽
- 不包括縮進和空格字符(比方逗號后的空格)
舉個例子:
function Person(name, secret) {
this.name = name;
this.secret = secret;
this.makeFriends = function() {
return this.secret;
}
}
Person.prototype.sayHi = function() {
return this.name;
}
var me = new Person("Sue", undefined)
me.makeFriends()
// undefined
me.sayHi()
// "Sue"
var meJSON = JSON.stringify(me);
// "{"name":"Sue"}"
上述例子中,我們建立了一個Person
實例me
,个中secret
屬性為undefined
,包括makeFriends
要領和一個原型成員sayHi
,這些都沒有被增加到天生的JSON字符串中。
這個要領能夠使我們沒必要在意Javascript語法與JSON語法的差別,只管建立正當的Javascript對象。
parse
用於把JSON字符串序列化為Javascript值。
var meCopy = JSON.parse(meJSON)
// {name: "Sue"}
*注重:me
與meCopy
是兩個自力的對象,現實編程中,能夠運用stringify
parse
完成對象的拷貝。
stringify 選項
JSON.stringify()
的第一個參數是要序列化的對象,背面還能夠加兩個參數,分別是過濾器和選項。
- 過濾器
過濾器能夠是數組,也能夠是函數,假如是數組,JSON.stringify()
的效果中將保存數組中的屬性,比方:
function Person(name, age, secret) {
this.name = name;
this.age = age;
this.secret = secret;
}
var me = new Person("Sue", 18, "none");
var meJSON = JSON.stringify(me, ["name", "age"])
meJSON
// "{"name":"Sue","age":18}"
假如過濾器是一個函數,會給這個函數傳入兩個參數,分別是屬性名和屬性值,根據需要返回要增加到JSON中的屬性值,假如為undefined
,會移除該屬性,比方:
var me = new Person("sue", 25, ["girl", "1024", "Beauty"])
function process(key, value) {
switch(key) {
case "name":
return value.charAt(0).toUpperCase() + value.slice(1);
case "age":
return 18;
case "secret":
return undefined;
default:
return value;
}
}
var meJSON = JSON.stringify(me, process)
meJSON
// "{"name":"Sue","age":18}"
- 字符串縮進
第三個參數用於掌握效果中的縮進和空白符,假如這個參數是一個數值,那末它示意每一個級別縮進的空格數,比方:
var meJSON = JSON.stringify(me, process, 4)
undefined
meJSON
"{
"name": "Sue",
"age": 18
}"
*注重:
- 只需傳入了縮進數,效果就會包括換行符,由於只縮進卻不換行沒什麼意義。
- 最大縮進為10,假如凌駕10, 轉換為10
假如第三個參數是一個字符串,那末將運用這個字符串作為縮進,這個字符串能夠是製表符或其他恣意字符,假如凌駕10位,則僅前10位有用,比方:
var meJSON = JSON.stringify(me, process, "\t")
meJSON
"{
"name": "Sue",
"age": 18
}"
var meJSON = JSON.stringify(me, process, "****")
meJSON
"{
****"name": "Sue",
****"age": 18
}"
- toJSON
當需要為某種對象增加自定義的序列化要領時,能夠給對象定義toJSON()
要領,比方:
Person.prototype.toJSON = function() {
return this.name;
}
var me = new Person("sue", 25, ["girl", "1024", "Beauty"])
JSON.stringify(me, process, "\t")
// ""sue""
上述例子中,我們在Person
的原型中增加了toJSON
要領,發明挪用JSON.stringify
時,只序列化了name
屬性。
序列化的內部遞次以下:
No. 1 假如存在toJSON()
,而且它能返回有用的值,則挪用它,不然,返回對象自身
No. 2 假如供應了過濾器參數,則基於第一步返回的值挪用過濾器
No. 3 序列化第二步的返回值
No. 4 假如供應了縮進,則花樣化第三步的返回值
parse 選項
JSON.parse()
能夠吸收第二個參數,這個參數是一個復原函數,將在每一個鍵值對上挪用,這個函數吸收兩個參數,分別是鍵和值,返回處理過的值,比方:
var birth = new Date(1993, 10, 24)
JSON.stringify(birth)
// ""1993-11-23T16:00:00.000Z""
var birthJSON = JSON.stringify(birth)
var birthCopy = JSON.parse(birthJSON, function(key, value) {
return new Date(value)
})
birthCopy.getFullYear()
// 1993