首頁 > 軟體

JavaScript物件與JSON格式的轉換及JSON.stringify和JSON.parse的使用方法

2022-07-28 22:02:21

JSON處理

JSONJavaScript Object Notation)是JavaScript表達值和物件的通用資料格式,其本質就是符合一定規範的字串。由於JSON的優良特性,非常容易和其他語言進行資料交換,尤其在前後端互動方面。即使我們前端使用JavaScript,後端使用Java/PHP/Python同樣可以使用JSON格式的資料輕鬆交換。

JSON.stringify

JavaScript為我們提供了簡單的方法可以實現物件和字串之間的轉化。

  • JSON.stringify將物件轉為JSON字串;
  • JSON.parseJSON字串轉為物件;

例如,我們把一個物件Dog使用 JSON.string轉為JSON字串:

let Dog = {
    name:'Peter',
    age:187,
    gender:'male',
    hands:['hand01','hand02','hand03','hand04'],
    childs:[
        {
            name:'little peter01',
            age:2,
            gender:'male',
            hands:['hand01','hand02','hand03','hand04'],
            childs:[]
        },
        {
            name:'little peter02',
            age:3,
            gender:'male',
            hands:['hand01','hand02','hand03','hand04'],
            childs:[]
        }
    ]
}
let dogJson = JSON.stringify(Dog)
console.log(typeof dogJson)
console.log(dogJson)

程式碼的執行效果:

可見,使用JSON.stringify(obj)方法會返回該物件objJSON字串資料,這個轉換的過程可以稱作JSON編碼(JSON-encoded)序列化(serialized),亦或者編組化(marshalled)。當物件轉為普通的字串後,我們就可以以普通資料的格式儲存、傳遞這些資料。

如果我們把這些字串寫入資料庫,就相當於把JavaScript物件存進了資料庫。

注意:

  • JSON編碼的物件統一使用雙引號,沒有單引號和反引號;
  • 物件的屬性名也用雙引號,這是強制的;

JSON已經發展成為了獨立的資料規範,因此歸屬於JavaScript語言本身的非資料屬性會被JSON.stringify跳過。

包括:

  • 物件方法;
  • Symbol型別
  • undefined的屬性
let user = {
    sayHello(){//函數被忽略
        console.log('hello world');
    },
    [Symbol('id')]:996996,//Symbol被忽略
    val:undefined//undefined值被忽略
}
console.log(JSON.stringify(user))

程式碼執行效果:

可以看到,裡面啥也沒有。

stringify的限制

並非所有的物件都能轉為JSON格式,如果物件之間存在迴圈參照,就會導致轉換失敗。

let father = {}
let son = {}
father.son = son
son.father = father
JSON.stringify(father)

程式碼執行結果:

這裡出現錯誤的原因就是存在物件間的迴圈參照,Father參照了Son,而Son又反過來參照了Father

排除和替換

如果我們只希望將物件的個別屬性轉為JSON格式,或者擺出迴圈應用中的屬性,應該怎麼做呢?

JSON.stringify已經為我們提供瞭解決方法:

let  json = JSON.stringify(obj[,replacer,space])

引數解讀:

obj:要編碼的物件replacer:要編碼的屬性陣列或者對映函數function(k,v)space:用於格式化的空格數量

舉個例子:

let father = {
    name:'father',
    age:28
}
let son = {
    name:'son',
    age:4
}
father.son = son;
son.father = father;
console.log(JSON.stringify(father,['name','age']))

程式碼的執行結果如下:

如果我們在第二個引數傳入一個陣列,那麼JSON.stringify就會只把陣列中的名稱轉為JSON格式,這樣計算物件存在迴圈參照,同樣能夠成功的轉格式。

如果我們希望序列化出迴圈應用外的所有物件屬性,只需要把物件的所有屬性名寫入陣列即可,這對物件的子物件同樣生效。

舉個例子:

let father = {
    name:'father',
    age:28,
    car:{
        car_name : "BYD",
        car_age:3,
    }
}
console.log(JSON.stringify(father,['name','car','car_name']))

程式碼執行結果:

但是,還存在一個問題,如果物件屬性特別多,可能陣列就會非常長,程式碼也會很冗長。

這種情況下就需要使用對映函數

對映函數

我們可以建立一個函數,代替陣列作為replacer,這個函數接收(key,value)作為引數,並決定如何序列化對應的屬性。

例如,在解決迴圈參照的時候,我們排除參照屬性:

let father = {
    name:'father',
    age:28,
    car:{
    	car_name : "BYD",
        car_age:3,
	}
}
let son = {
    name:'son',
    age:4
}
father.son = son;
son.father = father;
console.log(JSON.stringify(father,function replacer(key,value){
    console.log(`${key}:${value}`)
	return (key=='son')?undefined:value;
}))

程式碼執行結果如下:

由於值為undefined的屬性會被JSON.stringify忽略,這樣我們就可以輕鬆的排除所有不希望出現的屬性了。

格式化使用的空格數量

JSON.stringify(value, replacer, spaces)的第三個引數spaces可以指定JSON字串的縮排空格數,常用的數值有2、4兩種,相信童鞋們已經在編輯程式碼的時候有過修改縮排tab空格數的經歷了。

在上文案例中,我們沒有指定縮排空格數量,所以格式化後的JSON字串都是沒有格式的。

舉個例子:

let Dog = {
    name:'Peter',
    age:187,
    gender:'male',
    hands:['hand01','hand02','hand03','hand04'],
    childs:[
        {
            name:'little peter01',
            age:2,
            gender:'male',
            hands:['hand01','hand02','hand03','hand04'],
            childs:[]
        },
        {
            name:'little peter02',
            age:3,
            gender:'male',
            hands:['hand01','hand02','hand03','hand04'],
            childs:[]
        }
    ]
}
let dogJson = JSON.stringify(Dog,null,2)
console.log(dogJson)

程式碼的執行結果:

對比本文的第一個案例,是不是這樣的縮排看起來好看多了呢?

自定義toJSON方法

在之前的文章中,我們講到每個物件都有的toString方法,當進行格式轉換時會自動呼叫。和toString一樣,物件的toJSON方法會在序列化的時候呼叫,我們可以通過重寫這個方法改變序列化的方式。

例如:

let dog = {
    name : 'peter',
    age:18
}
console.log(JSON.stringify(dog))
dog.toJSON = function(){
    return this.age;
}
console.log(JSON.stringify(dog))

程式碼執行結果:

我們可以看到,在重寫了物件的toJSON方法後,使用stringify的結果發生了改變。

我們可以根據自己的需要重寫toJSON方法,從而達到自己的目的。

JSON.parse

上文講到了如何使用JSON.stringify把物件轉為JSON格式的字串,這裡就詳細介紹如何把JSON字串轉為物件。

語法:

let obj = JSON.parse(str,[reviver])

str 要解析的 JSON 字串。

reviver 可選的函數 function(key,value),該函數將為每個 (key, value) 對呼叫,並可以對值進行轉換。

例如:

let str_arr = '[1,2,3]'//陣列字串
let arr = JSON.parse(str_arr)
console.log(typeof arr)

程式碼執行結果:

對於複雜的巢狀物件:

let str_obj = `{
  "name": "Peter",
  "age": 187,
  "gender": "male",
  "hands": [
    "hand01",
    "hand02",
    "hand03",
    "hand04"
  ],
  "childs": [
    {
      "name": "little peter01",
      "age": 2,
      "gender": "male",
      "hands": [
        "hand01",
        "hand02",
        "hand03",
        "hand04"
      ],
      "childs": []
    },
    {
      "name": "little peter02",
      "age": 3,
      "gender": "male",
      "hands": [
        "hand01",
        "hand02",
        "hand03",
        "hand04"
      ],
      "childs": []
    }
  ]
}`
let obj = JSON.parse(str_obj)
console.log(obj.name)

程式碼執行結果:

注意:JSON不支援註釋,在JSON中新增註釋時錯誤的行為

有一種名為JSON5的格式,可以有不加引號的鍵、允許註釋,但是這是獨立的庫,補上官方標準。

常規的JSON格式嚴格,這樣是為了保證資料的可靠、快速解析演演算法

使用reviver

既然JSON.parse能夠直接轉字串為物件,為啥還要再搞reviver呢?

場景舉例:

如果我們有一個物件字串如下:

// title: (meetup title), date: (meetup date)
let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';

現在我們要將它轉為物件,存在什麼問題呢?

let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
let obj = JSON.parse(str)
obj.date.getDate();//Error

程式碼執行結果如下:

造成這種結果的原因是date屬性被轉為了字串,而不是Date物件。

這個時候就需要我們使用reviver函數將date轉為Date物件:

let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
let obj = JSON.parse(str,function(key,value){
    if(key=='date')return new Date(value)
    return value
})
obj.date.getDate();

程式碼執行效果:

順便說一下,這也適用於巢狀物件:

let schedule = `{
  "meetups": [
    {"title":"Conference","date":"2017-11-30T12:00:00.000Z"},
    {"title":"Birthday","date":"2017-04-18T12:00:00.000Z"}
  ]
}`;

schedule = JSON.parse(schedule, function(key, value) {
  if (key == 'date') return new Date(value);
  return value;
});

alert( schedule.meetups[1].date.getDate() ); // 正常執行了!

總結

  • JSON是一種資料格式,有獨立的標準和大多數程式語言的支援
  • JSON支援Object、array、string、number、boolean和nullJ
  • SON.stringify
  • JSON.parse

到此這篇關於JavaScript物件與JSON格式的轉換及JSON.stringify和JSON.parse的使用方法的文章就介紹到這了,更多相關JS與JSON格式轉換內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com