轻量数据格式 JSON


JSON 全名 JavaScript Object Notation,为 JavaScript 对象字面量(Object literal)的子集,你可以在〈Introducing JSON〉找到详细的 JSON 格式说明。大致而言,与对象字面量格式类似,主要注意的是JSON:

  • 名称为字符串,必须用 "" 双引号包括
  • 值可以是"双引号包括的字符串,或者是数字、true、false、null、对象或数组。
  • 不支持 JavaScript 的 Date、Error、规则表达式或函数表示。

举个例子来说,下面是个对象字面量:

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 方法。


展开阅读全文