<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
JSON
(JavaScript Object Notation
)是JavaScript
表達值和物件的通用資料格式,其本質就是符合一定規範的字串。由於JSON
的優良特性,非常容易和其他語言進行資料交換,尤其在前後端互動方面。即使我們前端使用JavaScript
,後端使用Java/PHP/Python
同樣可以使用JSON
格式的資料輕鬆交換。
JavaScript
為我們提供了簡單的方法可以實現物件和字串之間的轉化。
JSON.stringify
將物件轉為JSON
字串;JSON.parse
將JSON
字串轉為物件;例如,我們把一個物件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)
方法會返回該物件obj
的JSON
字串資料,這個轉換的過程可以稱作JSON編碼(JSON-encoded)、序列化(serialized),亦或者編組化(marshalled)。當物件轉為普通的字串後,我們就可以以普通資料的格式儲存、傳遞這些資料。
如果我們把這些字串寫入資料庫,就相當於把JavaScript
物件存進了資料庫。
注意:
JSON
編碼的物件統一使用雙引號,沒有單引號和反引號;JSON
已經發展成為了獨立的資料規範,因此歸屬於JavaScript
語言本身的非資料屬性會被JSON.stringify
跳過。
包括:
let user = { sayHello(){//函數被忽略 console.log('hello world'); }, [Symbol('id')]:996996,//Symbol被忽略 val:undefined//undefined值被忽略 } console.log(JSON.stringify(user))
程式碼執行效果:
可以看到,裡面啥也沒有。
並非所有的物件都能轉為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)
程式碼的執行結果:
對比本文的第一個案例,是不是這樣的縮排看起來好看多了呢?
在之前的文章中,我們講到每個物件都有的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.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
格式嚴格,這樣是為了保證資料的可靠、快速解析演演算法
既然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() ); // 正常執行了!
到此這篇關於JavaScript物件與JSON格式的轉換及JSON.stringify和JSON.parse的使用方法的文章就介紹到這了,更多相關JS與JSON格式轉換內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45