JavaScript 語言核心(17)輕量資料格式 JSON



JSON 全名 JavaScript Object Notation,為 JavaScript 物件實字(Object literal)的子集,你可以在 Introducing JSON 找到詳細的 JSON 格式說明。大致而言,與物件實字格式類似,主要注意的是JSON:
  • 名稱為字串,必須用 "" 雙引號包括
  • 值可以是"雙引號包括的字串,或者是數字、truefalsenull、物件或陣列。
  • 不支援 JavaScript 的 DateError、規則表示式或函式表示。
舉個例子來說,下面是個物件實字:
var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};
若使用JSON表示,則是如下:
var json = '{"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}';
若為排版會比較容易觀察:
{
    "name":"Justin",
    "age":35,
    "childs":[
        {
            "name":"hamimi",
            "age":3
        }
    ]
}

JSON.stringify

ECMAScript 5 規範中,如果要從物件建立 JSON 字串,只要使用 JSON.stringify。例如:
var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};

var json = JSON.stringify(obj);

// {"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}
console.log(json);

//{"name":"Justin","age":35}
console.log(JSON.stringify(obj, ['name', 'age']));
JSON.stringify 可以指定第二個引數,若指定陣列,只會針對該陣列轉換 JSON 字串,若指定函式,這個函式可接受物件的特性與值,可以自行決定如何轉換為 JSON 字串。
第一次呼叫指定函式時,鍵為空字串,而值為要被轉換的物件本身,之後逐一以每個特性與值來呼叫函式,傳回值若是數字、字串、布林值,就會被加入 JSON 字串,如果傳回物件,則會遞迴地呼叫指定的函式進行轉換,如果傳回 undefined,該特性就不會被加入 JSON 字串。
例如,上頭的 obj 轉換為 JSON 字串時,不想要有 age 特性的話,可以如下:
var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};

console.log(JSON.stringify(obj, function(key, value) {
    if(key === 'age'){
        return undefined;
    } 
    return value;
}));
JSON.stringify 可以指定第三個引數,如果是 1 到 10 的數字,會自動換行並以指定數字作為縮排層次,如果指定字元,就會以指定的字元來進行縮排。例如:
var obj = {
    name : 'Justin',
    age : 35,
    childs : [ {name : 'hamimi', age : 3} ]
};

function replacer(key, value) {
    return key === 'age' ? undefined : value;
}

console.log(JSON.stringify(obj, replacer, 2));
顯示的結果會是兩個空格縮排:
{
  "name": "Justin",
  "childs": [
    {
      "name": "hamimi"
    }
  ]
}
如果物件本身定義有 toJSON 方法,JSON.stringify 會使用 toJSON 傳回的物件來進行 JSON 字串轉換。例如:
var obj = {
    name : 'Justin',
    age : 35,
    toJSON : function() {
        return {
            name : this.name.toUpperCase(), 
            age  : this.age
        };
    }
};

// {"name":"JUSTIN","age":35}
console.log(JSON.stringify(obj));

JSON.parse

如果想將 JSON 字串剖析為 JavaScript 物件,可以使用 JSON.parse,例如:
var json = '{"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}';
var obj = JSON.parse(json);

console.log(obj.name); // Justin
每個鍵值被剖析為值之後,可以指定一個函式來決定被剖析後的值如何轉換,傳回的值決定了最後得到的物件上之特性值,如果傳回 undefined,就不會包括該特性。例如:
var json = '{"name":"Justin","age":35,"childs":[{"name":"hamimi","age":3}]}';

var obj = JSON.parse(json, function(key, value) {   
    if(key === 'age'){
        return undefined;
    } 
    return value;
});

console.log(obj); // { name: 'Justin', childs: [ { name: 'hamimi' } ] }
如果是沒有內建 JSON 支援的平台(像是一些舊瀏覽器),可以在 Introducing JSON 下載 json2.js,用以獲得上述的相關 JSON 方法。