天天看點

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 }