Javascript JSON

JSON只是一種字符串數據格式,使用它的不單單是Javascript。git

語法

JSON能夠表示三種類型的值:簡單值、對象、數組github

簡單值

如下是JSON能夠辨識的簡單值例子:web

5
"Hello World!"
false
null

*注意:編程

  1. undefined不被支持
  2. 字符串必須使用雙引號,單引號會致使語法錯誤

對象

在Javascript中,咱們能夠用對象字面量的方式建立一個對象:數組

var person = {
    name: "Sue",
    age:  "18"
}

但JSON要求給屬性加雙引號,上述對象轉換成合法的JSON字符串格式:瀏覽器

{
    "name": "Sue",
    "age":  "18"
}

*注意:服務器

  1. 屬性加雙引號
  2. 沒有變量聲明
  3. 沒有末尾分號
  4. 屬性的值能夠是前面介紹的簡單值,也能夠是對象或數組
  5. 二、3點一樣適用於簡單值和數組

數組

在Javascript中,咱們能夠建立一個以下數組:函數

var names = ["Sue", "Jane", "Ben"]

上述數組轉換成合法的JSON字符串格式:this

["Sue", "Jane", "Ben"]

咱們能夠將數組、簡單值、對象嵌套使用,建立更加複雜的JSON字符串,好比:prototype

{
    "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字符串。
*注意:

  1. 值爲undefined的屬性會被忽略
  2. 函數及原型成員會被忽略
  3. 不包含縮進和空格字符(好比逗號後的空格)

舉個例子:

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"}

*注意:memeCopy是兩個獨立的對象,實際編程中,可使用stringify parse實現對象的拷貝。

stringify 選項

JSON.stringify()的第一個參數是要序列化的對象,後面還能夠加兩個參數,分別是過濾器和選項。

  1. 過濾器

過濾器能夠是數組,也能夠是函數,若是是數組,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}"
  1. 字符串縮進

第三個參數用於控制結果中的縮進和空白符,若是這個參數是一個數值,那麼它表示每一個級別縮進的空格數,好比:

var meJSON = JSON.stringify(me, process, 4)
undefined
meJSON
"{
    "name": "Sue",
    "age": 18
}"

*注意:

  1. 只要傳入了縮進數,結果就會包含換行符,由於只縮進卻不換行沒什麼意義。
  2. 最大縮進爲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
}"
  1. 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
相關文章
相關標籤/搜索