JSON 筆記

ac黃發表於2015-03-05

JSON 全稱為 JavaScript Object Notation(JavaScript物件表示法),它利用與 JavaScript 物件相似的表示方法來表示資料。雖然 JSON 脫胎於 JavaScript,但是 JSON 並不屬於 JavaScript 的一部分,很多的語言都可以解析和序列化 JSON。

JSON 語法

JSON 可以表示以下三種型別的值:

  • 簡單值

  • 物件

  • 陣列

簡單值包括字串、數值、布林值和 null。但是要注意的是 JSON 不能表示 JavaScript 當中的一種特殊值 undefinde

物件,與 JavaScript物件相似,表示無序的鍵值對。鍵值對中的值可以是簡單值,也可以是物件或陣列。

陣列,與 JavaScript陣列相似,表示一組有序的值,陣列的值可以是簡單值,也可以是物件或陣列。

舉個例子:

{
    "name": "acwong",
    "age": 23,
    "address": {
        "province": "GuangDong",
        "city": "GuangZhou"
    },
    "friends": ["bc", "cc", "dc"],
    "blog": "http://acwong.org"
}

需要注意的是,也是與 JavaScript物件表示方法的不同之處,JSON 字串當中物件的屬性必須加上雙引號

// 正確示範
{
    "name": "acwong"
}

// 錯誤示範
{
    name: "acwong"
}
// 單引號也是錯誤的
{
    `name`: `acwong`
}

JavaScript 與 JSON

JSON 物件

在 JSON 誕生之初 JavaScript 處理 JSON 的方式基本就靠 eval() 函式。

eval() 函式可以解析 JSON 然後返回 JavaScript 陣列。但是由於 eval() 存在安全的風險,因此在 EMCAScript 5 開始有了一個新的全域性物件 JSON物件用來處理 JSON。

序列化 JSON

JavaScript 使用 JSON物件的 stringify() 方法來序列化 JSON。

var person = {
    name: "acwong",
    age: 23,
    address: {
        province: "GuangDong",
        city: "GuangZhou"
    },
    friends: ["bc", "cc", "dc"],
    blog: "http://acwong.org"
};

var jsonText = JSON.stringify(person);

console.log(jsonText);
// {"name":"acwong","age":23,"address":{"province":"GuangDong","city":"GuangZhou"},"friends":["bc","cc","dc"],"blog":"http://acwong.org"}

JSON.stringify() 方法在預設情況下輸出的 JSON字串不包含空格字元和縮排。

如果 JavaScript物件當中包含不被 JSON 支援的型別(如:undefined,函式)會自動被 stringigy() 方法忽略。

var person = {
    name: "acwong",
    blog: undefined,
    todo: function() {
        return "sleep";
    }
};

var jsonText = JSON.stringify(person);

console.log(jsonText);
// {"name":"acwong"}

JSON.stringify() 方法包含三個引數,第一個引數就是要序列化的 JavaScript物件。第二個引數完成過濾輸出結果功能。第三個引數控制輸出字串的縮排

過濾輸出結果

第二個引數完成過濾輸出結果功能。

當傳入的第二個引數為陣列時,輸出的 JSON字串只會保留包含在該陣列裡面的屬性值。

var person = {
    name: "acwong",
    age: 23,
    address: {
        province: "GuangDong",
        city: "GuangZhou"
    },
    friends: ["bc", "cc", "dc"],
    blog: "http://acwong.org"
};

var jsonText = JSON.stringify(person, ["name","blog"]);

console.log(jsonText);
// {"name":"acwong","blog":"http://acwong.org"}

當傳入的第二個引數為函式,該函式包含兩個引數,分別是 JavaScript物件的屬性名和屬性值。輸出的 JSON字串會受到該函式的返回值影響。

// 省略 person物件
var jsonText = JSON.stringify(person, function(key, value) {
    if (key === "name") {
        return "ac";
    } else if (key === "age") {
        value++;
        return value;
    } else {
        return value;
    }
});

console.log(jsonText);
// {"name":"ac","age":24,"address":{"province":"GuangDong","city":"GuangZhou"},"friends":["bc","cc","dc"],"blog":"http://acwong.org"}

控制縮排

第三個引數控制輸出字串的縮排

當第三個引數傳入一個數值的時候,表示輸出字串縮排的空格數。

// 省略 person物件
var jsonText = JSON.stringify(person, null, 2);

console.log(jsonText);
// 輸出
{
  "name": "acwong",
  "age": 23,
  "address": {
    "province": "GuangDong",
    "city": "GuangZhou"
  },
  "friends": [
    "bc",
    "cc",
    "dc"
  ],
  "blog": "http://acwong.org"
}

當第三個引數傳入一個字串時,輸出結果會以該字串作為縮排符號。

// 省略 person物件

// 使用 * 號縮排
var jsonText = JSON.stringify(person, null, "*");

console.log(jsonText);
// 輸出
 {
*"name": "acwong",
*"age": 23,
*"address": {
**"province": "GuangDong",
**"city": "GuangZhou"
*},
*"friends": [
**"bc",
**"cc",
**"dc"
*],
*"blog": "http://acwong.org"
}
// 省略 person物件

// 使用製表符(Tab)縮排
var jsonText = JSON.stringify(person, null, "	");

console.log(jsonText);
// 輸出
 {
    "name": "acwong",
    "age": 23,
    "address": {
        "province": "GuangDong",
        "city": "GuangZhou"
    },
    "friends": [
        "bc",
        "cc",
        "dc"
    ],
    "blog": "http://acwong.org"
}

自定義序列化

如果上述的方法都不能滿足要求,還可以在要序列化的 JavaScript物件當中加入 toJSON() 函式,可以返回任何想返回的值。

var person = {
    name: "acwong",
    age: 23,
    address: {
        province: "GuangDong",
        city: "GuangZhou"
    },
    friends: ["bc", "cc", "dc"],
    blog: "http://acwong.org",
    toJSON: function() {
        this.name = "ac";
        return "yoyo " + this.name;
    }
};

var jsonText = JSON.stringify(person);

console.log(jsonText);
//  "yoyo ac"

解析 JSON

JavaScript 使用 JSON物件的 parse() 方法來解析 JSON。

var jsonText = `{"name":"acwong","age":23,"address":{"province":"GuangDong","city":"GuangZhou"},"friends":["bc","cc","dc"],"blog":"http://acwong.org"}`;

var person = JSON.parse(jsonText);

console.log(person);

圖片描述

JSON.parse() 同樣可以傳入一個函式作為引數,對鍵值對進行操作。

var jsonText = `{"name":"acwong","age":23,"blog":"http://acwong.org"}`;

var person = JSON.parse(jsonText);

console.log(person);

圖片描述

JSON 的好處

  1. 與 XML 一樣可以表示複雜的資料結構。

  2. 比 XML 輕量得多。

  3. 語法簡單易懂。

  4. 由於其輕量級,在傳輸的時候佔用的資源相對較少。

感謝您的閱讀,有不足之處請為我指出。

參考

JavaScript高階程式設計(第3版)

本文同步於我的個人部落格 http://blog.acwong.org/2015/03/05/json-notes/

相關文章