JSON详解

本文尝试详解下JSON对象的两个方法,以及JSON的一些基本的姿势。

JSON的数据结构


  • JSONObject:
    以”{“开始,”}”结束。每个”名称”后跟一个”:”(冒号);”‘名称/值’ 对”之间使用”,”(逗号)分隔。
  • JSONArray:
    以”[“(左中括号)开始,”]”(右中括号)结束。值(value)之间使用”,”(逗号)分隔。
    值(value)包括必须为双引号包含的string,number,boolean,null,object,array。
  • JSONString
    JSONString由双引号包裹,且不含 “、\、\ 、U+0000至U+001F十九个control字符、空白符、16进制Unicode符
  • JSONNumber
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    SONNumber = - PositiveNumber
    or PositiveNumber
    PositiveNumber = DecimalNumber
    or DecimalNumber . Digits
    or DecimalNumber . Digits ExponentPart
    or DecimalNumber ExponentPart
    DecimalNumber = 0
    or OneToNine Digits
    ExponentPart = e Exponent
    or E Exponent
    Exponent = Digits
    or + Digits
    or - Digits
    Digits = Digit
    or Digits Digit
    Digit = 0 through 9
    OneToNine = 1 through 9

与JavaScript的区别


  • 属性名必须为双引号包裹的字符串,逗号后面为空是不合法的
  • JSONNumber不能以0开头且小数点后面至少跟一位数字
  • 可以正切解析Unicode line separator (U+2028) and paragraph separator (U+2029) characters,JavaScript中是无法解析的

JSON.parse(text[, reviver]):


将符合JSON格式的并用字符串包裹的JSON文本转换为JSON对象。
当指定函数时,默认两个参数分别为被解析对象的key/value值,最后一个key为””,return值为:

1
2
3
4
5
6
7
8
9
10
var js=[{"a":1},{"b":2},{"c":3}],
mi = JSON.stringify(js),
filter=[];
var sss = JSON.parse(mi, function(k, v) {
//console.log(k);
if (k!== 'b' && (typeof v)!="object") { filter.push(v) } // if topmost value, return it,
return v; // else return v * 2.
});
console.log(filter);
console.log(sss);

这里我们可以模拟一个后台传过来的json序列化数据用JSON.parse()解析并过滤出我们想要的值(这他么方法会不会出问题不知道。。。效率我也不知道,别问我。。。);

JSON.stringify(value[, replacer[, space]]):


stringify方法三个参数,第一个参数为被序列化的JavaScript值,第二个为一个函数或者一个数组,当第二个参数为null,时可以指定第三个字符串参数

  • 第二个参数为函数时

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    var foo = {foundation: "Mozilla",transport: "", month: 7};
    JSON.stringify(foo, replacer);
    > 当function中的return 值为一个string时,那么用该string替代当前遍历到的值:
    function replacer(key, value) {
    if (!value) {
    return "message"; //此时value为""
    }
    return value;
    }
    结果为'{foundation: "Mozilla",transport: "message", month: 7}'
    > 如上当function中的return值为一个number时,用该number替代当前遍历到的值
    > 如上当function中的return值为一个boolean时,用该boolean替代当前遍历到的值
    > 如上当function中的return值为一个object时,用该object替代当前遍历到的值,为function时当前遍历的键值对不显示
    > 如上当function中的return值为一个undefined时,当前遍历到的键值对将不显示在返回的JSONString中。对数组进行序列化的情况下,此时的undefined会被null替换而非不显示。
  • 第二个参数为函数时

    1
    2
    JSON.stringify(foo, ['week', 'month']);
    //过滤出key为week和month的键值对
  • 当第二个参数为null,可以指定第三个字符串参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    > 第三个为空格时序列化之后的JOSNString为下面这样
    JSON.stringify({ a: 2 }, null, ' ');
    '{
    "a": 2
    }'
    > 第三个为"\t"时序列化之后的JOSNString为下面这样
    '{
    "a": 2
    }'
    当然,联想下为"\r"等其他呢,自己去试试吧
  • 当被序列化的JavaScript值为一个object且包含一个key为”toJson”,value为一个function时,此时的序列化会受到该toJSON方法的影响

    1
    2
    3
    4
    5
    6
    7
    8
    var obj = {
    foo: 'foo',
    toJSON: function() {
    return 'bar';
    }
    };
    JSON.stringify(obj); // '"bar"'
    JSON.stringify({ x: obj }); // '{"x":"bar"}'