天天看点

JavaScript标准库- JSON对象

JSON

: JavaScript Object Notation,是一种用于数据交换的文本格式.

  1. 复合类型的值只能是数组或对象,不能是

    函数

    正则表达式对象

    日期对象

  2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和

    null

    (不能使用

    NaN

    ,

    Infinity

    ,

    -Infinity

    undefined

    )。
  3. 字符串必须使用双引号表示,不能使用单引号。
  4. 对象的键名必须放在双引号里面。
  5. 数组或对象最后一个成员的后面,不能加逗号。

JSON对象的两个静态方法 - JSON.stringify()

-  JSON.stringify():用于将一个值转为JSON字符串(该字符串符合JSON格式,并且可以被JSON.parse()方法还原)
      let obj = {
      name: "中小余",
      age: 18,
      gender: "女",
      like:undefined, //  undefined也不会被转换
      say: function() { // 不能是函数,所以不会转换
        return "hello word.";
      }
    };
    JSON.stringify(obj); // '{"name":"中小余","age":18,"gender":"女"}' 
	 
	* 对象的属性是undefined、函数或XML对象,该属性会被JSON.stringify()过滤
	JSON.stringify(false) // "false"
	JSON.stringify('false') // "\"false\""  字符串false为了跟布尔值false区分 转换后会在前后加 "\"
	* 数组的成员是undefined、函数或XML对象,则这些值会被转换成null
	let arr = [undefined,function(){}];
	JSON.stringify(arr); //'[null,null]'
	
	* 正则会被转换为空对象
	JSON.stringify(/xx/);//'{}'

	* 它还会忽略对象的不可遍历的属性(enumerable属性为false时)
	let obj = {};
    Object.defineProperties(obj,{
      'name':{
        value:1,
        enumerable:true
      },
      'age':{
        value:18,
        enumerable:false
      }
    })
    JSON.stringify(obj); // '{"name":1}' age被忽略了
	
- JSON.stringify() 可以有第二个参数:
	/* JSON.stringify()方法还可以接受一个数组,作为第二个参数,指定参数对象的哪些属性需要转成字符串。
	*/
	* 相当于白名单,但只对对象的属性有效,对数组无效。
		let obj = {
          name:'中小余',
          age:18,
          gender:'女',
          likeWord:'一勤天下无难事'
        };
        let selectedProperty = ['name','likeWord']; // 白名单
        JSON.stringify(obj,selectedProperty);
		// '{"name":"中小余","likeWord":"一勤天下无难事"}'   数组里没有的都不会被转化

	* 第二个参数还可以是一个函数,用来更改JSON.stringify()的返回值
    	let obj = {
         num1:10,
         num2:2
        };
        function fun(key,value){
          console.log(key);
          console.log(value);
          if(typeof value === 'number'){
            value = 2 * value; 
          }
          return value;
        }

        JSON.stringify(obj,fun); // '{"num1":20,"num2":4}'  递归处理函数所有的键,每一次处理的对象,都是前一次返回的值;如果处理函数返回undefined或没有返回值,则该属性会被忽略。

- 第三个参数:用于增加返回的 JSON 字符串的可读性。
	let obj = {
      name:'中小余',
      age:18,
      gender:'女',
      likeWord:'一勤天下无难事'
    };
    JSON.stringify(obj,null,'\t');//  \t在每个属性前面添加一个制表符,然后分行显
	/*
	`{
	"name": "中小余",
	"age": 18,
	"gender": "女",
	"likeWord": "一勤天下无难事"
    }`
	*/	
	JSON.stringify(obj,null,2);// 在每个属性前面添加的空格数(最多不超过10个)。
	/*`{
      "name": "中小余",
      "age": 18,
      "gender": "女",
      "likeWord": "一勤天下无难事"
    }`*/
           

toJson()

如果参数对象有自定义的

toJSON()

方法,那么

JSON.stringify()

会使用这个方法的返回值作为参数,而忽略原对象的其他属性。

let obj = {
   name: "中小余",
   age: 18,
   gender: "女",
   like:'一勤天下无难事', 
   say: function() { 
     return "hello word.";
   },
   toJSON: function(){
     return  this.name + this.like
   }
 };
JSON.stringify(obj); // '"中小余一勤天下无难事"'  
// JSON.stringify()发现参数对象有toJSON()方法,就直接使用这个方法的返回值作为参数,而忽略原对象的其他参数。
           
- Date对象就有一个自己的toJSON()方法
    let now = new Date();
    now.toJSON(); //'2021-04-07T14:00:34.444Z'
    JSON.stringify(now);// '"2021-04-07T14:00:34.445Z"'
           

toJSON()

方法的一个应用是,将正则对象自动转为字符串。因为

JSON.stringify()

默认不能转换正则对象,但是设置了

toJSON()

方法以后,就可以转换正则对象了。

let obj = {
    reg:/xxx/
}
// 不设置toJSON方法时
JSON.stringify(obj); //'{"reg":{}}'
// 设置toJSON方法
RegExp.prototype.toJSON = RegExp.prototype.toString;
JSON.stringify(obj); // '{"reg":"/xxx/"}'
           

JSON.parse():方法用于将 JSON 字符串转换成对应的值

var yuInfo = JSON.parse('{"name": "中小余"}');
yuInfo.name; // '中小余'
// 如果传入的字符串不是有效的 JSON 格式,JSON.parse()方法将报错。

- 为了处理解析错误,可以将JSON.parse()方法放在try...catch代码块中
try{
  JSON.parse('zhongxiaoyu');
} catch(e){
  console.log('error');
}
// 'error'

- JSON.parse()方法可以接受一个处理函数,作为第二个参数,用法与JSON.stringify()方法类似
	function f(key, value) {
      if (key === 'a') {
        return value + 10;
      }
      return value;
    }

    JSON.parse('{"a": 1, "b": 2}', f); // { a: 11, b: 2 }