关于JSON的总结

一、前言

最近学习并使用Vue的过程中,在使用Vue-resource的过程中遇到了以下问题:通过该插件异步请求数据的时候发现数据已经能正确请求到,但是无法通过response.json()解析返回体的body。通过查阅源码,发现该函数的主要作用就是将response对象中的body通过JSON.parse(this.body)解析为json对象。至于为什么会出现解析错误的情况,是因为自己写的json格式出现了错误,因此对json对象做了如下的总结。

二、JSON格式

1. 什么是json

json(Javascript Object Notation)是一种用于数据交换的文本格式。2001年由Douglas Crockford提出,目的是取代繁琐笨重的XML格式。

2. json格式与xml的比较

与同样作为数据传输的格式的xml比起来,json具有以下优点:
- 书写简单,结构清晰,轻量级
- 符合javascript的原生语法,解释器引擎可以直接处理

3. 对于json格式的几个规定:

  • 数组或对象的值可以是简单值也可以是复合值
  • 简单值包括:字符串、数值(必须是十进制标识)、布尔值和Null,其中(NaN,Infinity,-Infinity和undefined都会被转换为null)
  • 复合值包括符合json格式的数组或对象
  • 数组或对象的最后一个成员后面不能加逗号
  • 数组或对象之中的字符串必须使用双引号,不能使用单引号
  • 对象的成员名称必须使用双引号

注意:空数组或者空对象都是合格的json值,Null也是一个合格的json值
正确的json格式,例如:

["one", "two", "three"] //数组    

{ "one": 1, "two": 2, "three": 3 }//对象,注意成员名称必须用双引号

{"names": ["张三", "李四"] }//值为复合对象

[ { "name": "张三"}, {"name": "李四"} ]//对象数组

三、json对象

ES5中添加了json对象,其包含两个方法:JSON.stringify()和JSON.parse()

1. JSON.stringify()
用处:将一个值转换为json格式的字符串,该字符串可以被JSON.parse()解析,需要注意以下几点:

  • 原始类型的字符串解析后会自动加上双引号
  • 原始对象中如有一个成员是undefined,函数或者是xml对象,则这个成员被忽略
  • 原始对象中如果数组的成员的是undefined,函数或者是xml对象,则被转换为null
  • 正则表达式会被转换为空对象
  • 自动忽略原始对象中不可遍历的属性
  • 可以接受一个数组参数,指定需要转换成字符串的属性
  • 可以接受一个函数作为参数,指定如何来转换成字符串,注意该函数是递归处理所有的键
  • 如何被转换的对象中包含一个toJSON方法,则会使用该方法的返回值,将该返回值转换为字符串,忽略其他成员(可以被用来处理转换正则表达式的情况)

2. JSON.parse()
用处:用来将json格式的字符串转换为对象。如果该json字符串不符合json格式,则会报错。

3. 示例


        console.log(JSON.stringify('abc'));//""abc""字符串默认加上双引号
        console.log(JSON.stringify(1));//"1"
        console.log(JSON.stringify(false) );//"false"
        console.log(JSON.stringify([]));//"[]"
        console.log(JSON.stringify({}));//"{}"
        console.log(JSON.stringify([1, "false", false]));//"[1, "false", false]"
        console.log(JSON.stringify({ name: "张三" }));//"{"name":"张三"}" 成员名称双引号
        console.log(JSON.stringify({
                    f: function(){},
                    a: [ function(){}, undefined ]
                }));//"{"a":[null,null]}"
        console.log(JSON.stringify(/foo/));//"{}"正则表达式会被转换为空对象

以上代码中需要注意:

  • 关于字符串的转换需要加双引号
  • 成员名要加双引号
  • 对于被转换对象中某个成员是函数、undefined、xml对象直接忽略。这三种情况在数组中出现时被转换为null
  • 正则表达式会被转换为空对象

        var obj = {};
        Object.defineProperties(obj, {
          'foo': {
            value: 1,
            enumerable: true
          },
          'bar': {
            value: 2,
            enumerable: false
          }
        });

        console.log(JSON.stringify(obj)); // {"foo":1}

以上代码中需要注意:JSON.stringify只能转换对象中可遍历的属性,不可遍历的属性自动忽略

var obj = {
  'prop1': 'value1',
  'prop2': 'value2',
  'prop3': 'value3'
};

var selectedProperties = ['prop1', 'prop2'];

console.log(JSON.stringify(obj, selectedProperties));// "{"prop1":"value1","prop2":"value2"}"

以上代码中需要注意:可以给JSON.stringify指定额外一个数组参数,用来指定将对象中哪些属性转换为字符串

function change(key, value) {
 if (typeof value === "number") {
    value = 2 * value;
  }
  return value;
}

console.log(JSON.stringify({ a: 1, b: 2 }, change));
// '{"a": 2,"b": 4}'

以上代码中需要注意的是:可以给JSON.stringify指定一个函数参数,用来改变转换字符串过程中的行为

var o = {a: {b: 1}};

function f(key, value) {
  console.log("["+ key +"]:" + value);
  return value;
}

console.log(JSON.stringify(o, f));
// []:[object Object]
// [a]:[object Object]
// [b]:1
// '{"a":{"b":1}}'

以上代码说明了如果指定JSON.stringify的函数参数,处理函数是递归的处理每一个键值对。因此看下一个例子:

var o = {a: 1};

function change(key, value){
  if (typeof value === "object"){
    return {b: 2};
  }
  return value * 2;
}

console.log(JSON.stringify(o,change));
// "{"b": 4}"

在上面的代码中形象的体现了这一点,函数是递归来处理的。首先第一次递归,将该对象转换成了{b: 2},然后接下里的递归中根据该改变后的对象值进行递归,因此打印出来的是{b:4}

function f(key, value) {
 if (typeof(value) == "string") {
    return undefined;
  }
  return value;
}

console.log(JSON.stringify({ a:"abc", b:123 }, f));
// '{"b": 123}'

以上代码中需要注意的是:如果处理函数中返回了undefined或者没有返回值,则该属性被忽略

console.log(JSON.stringify({ p1: 1, p2: 2 }, null, 2));
/* 
"{
  "p1": 1,
  "p2": 2
}"
*/

console.log(JSON.stringify({ p1:1, p2:2 }, null, "|-"));
/*
"{
|-"p1": 1,
|-"p2": 2
}"
*/

以上代码中需要注意的是:可以给JSON.stringify()指定第三个参数,用来格式化输出的字符串。如果是数字,则表示每个属性前面添加的空格,如果是字符串,则加在每行输出的前面。

console.log(JSON.stringify({
 toJSON: function() {
    return "Cool"
  }
}));
// "Cool""

var o = {
  foo: 'foo',
  toJSON: function() {
    return 'bar';
  }
};
console.log(JSON.stringify({x: o})); 
// '{"x":"bar"}'

以上代码中需要注意的是:如果被转换的对象中含有toJSON方法,则使用toJSON的返回值进行转换,其他属性忽略。

RegExp.prototype.toJSON = RegExp.prototype.toString;

console.log(JSON.stringify(/foo/));
// "/foo/"

以上代码就是toJSON的一个应用,用来对正则表达式应用JSON.stringify。


该篇对于json的学习主要来源于阮一峰老师的教程。
参考文章:JavaScript 标准参考教程(alpha)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值