對於JSON,相信你們應該都蠻熟悉的.無論是前端仍是後端的童鞋,應該天天都會和JSON打交道吧.JSON是 JavaScript Object Notation(JavaScript對象表示法)的縮寫,是一種輕量級的文本數據交換格式,比xml更小,更快,更易於解析javascript
在JavaScript中,JSON對象包含兩個方法,parse()
和stringify()
,前者用於反序列化,後者用於序列化.所謂的序列化,通俗的理解就是將一個對象變成字符串,而反序列化就是相對應相反的過程.前端
今天咱們主要來說講其中的stringify()
方法.雖然咱們平時也都在用這個方法,可是咱們每每會忽略這個方法的更進一步的用法.假如咱們能用好這個方法,在實際的開發過程當中就能夠達到事半功倍的效果.java
相信你們在平時的開發過程當中,常常會用到console.log
來打印輸出結果.好比咱們在下面打印一個對象:json
let obj = {
name:'zhangsan',
age:undefined
}
console.log(obj) // // {name: "zhangsan", age: undefined}
複製代碼
能夠很清晰的在控制檯輸出結果,達到咱們想要的結果.可是假如咱們對象中的有的屬性值是沒有意義的.好比下面的代碼中,年紀是個未定義的屬性,咱們不想要在控制檯輸出它該怎麼辦.這時就可使用JSON.stringify()
方法來達到過濾的目的後端
let obj = {
name:'zhangsan',
age:undefined
}
console.log(JSON.stringify(obj)) // {"name":"zhangsan"}
複製代碼
咱們能夠看到此時的輸出結果就已經把屬性值爲undefined
這個age
屬性給過濾掉了.而這正是JSON.stringify()
的其中一個特性.除了undefined
之外,屬性值爲任意函數或者symbol
類型的,也會被過濾掉.數組
let obj = {
name:'zhangsan',
age:undefined,
f:() => { console.log(1) },
symbol:Symbol('This is a symbol')
}
console.log(JSON.stringify(obj)) // {"name":"zhangsan"}
複製代碼
咱們再來給這個對象添加一個屬性.此次咱們添加的是一個數組,而這個數組裏面就有一些上面咱們提到過的這些類型,結果又是如何呢?函數
let obj = {
name:'zhangsan',
age:undefined,
f:() => { console.log(1) },
symbol:Symbol('This is a symbol'),
arr:[1, undefined, 2, this.f, 3, Symbol('This is a symbol in array')]
}
console.log(JSON.stringify(obj)) // {"name":"zhangsan","arr":[1,null,2,null,3,null]}
複製代碼
能夠看到,undefined
,函數和symbol
類型的都變成了null
. 下面咱們還要用這幾個類型來測試,假如咱們直接使用JSON.stringify()
來操做它們會怎麼樣呢?測試
console.log(JSON.stringify(undefined)) // undefined
console.log(JSON.stringify(() => { console.log(1) })) // undefined
console.log(JSON.stringify(Symbol('This is a symbol'))) // undefined
複製代碼
能夠看到輸出結果全是undefined
.咱們再來看看其餘的某些特殊的值:ui
console.log(JSON.stringify(null)) // null
console.log(JSON.stringify(NaN)) // null
console.log(JSON.stringify(Infinity)) // null
複製代碼
能夠看到null
,NaN
,Infinity
之類的都變成了null
.this
下面咱們來看看轉換包裝對象的結果
console.log(JSON.stringify(new String('str'))) // "str"
console.log(JSON.stringify(new Boolean(true))) // true
console.log(JSON.stringify(new Number(1))) // 1
複製代碼
能夠看出字符串,布爾類型和數字的包裝對象會在序列化的時候變成原始值
假如咱們轉換對象中有toJSON
這個方法,那麼返回的結果就由它決定:
let obj = {
name:'zhangsan',
toJSON:function(){
return 'customize return value'
}
}
console.log(JSON.stringify(obj)) // "customize return value"
複製代碼
若是顯示的定義了toJSON
方法卻沒有return
任何內容,那麼結果就是undefined
let obj = {
name:'zhangsan',
toJSON:function(){}
}
console.log(JSON.stringify(obj)) // undefined
複製代碼
這裏又能夠牽扯出另一個對象類型Date
.假如咱們序列化一個Date
類型,結果又是什麼呢?
console.log(JSON.stringify(new Date())) // "2020-06-20T14:21:15.071Z"
複製代碼
能夠看到輸出了這種咱們熟悉的時間格式,這是由於Date
類型的對象就有本身的toJSON
的實現
假如一個對象的屬性是不可枚舉的,那麼也會被過濾掉
let obj = Object.create({},{
name:{
value:'zhangsan',
enumerable:false
},
age:{
value:18,
enumerable:true
}
})
console.log(obj) // {age: 18, name: "zhangsan"}
console.log(JSON.stringify(obj)) // {"age":18}
複製代碼
到上面爲止,咱們舉例了一些JSON.stringify()
的用法.不少人覺得到這裏就結束了,其實不是的,下面咱們還要介紹它的第2個參數.
假若有這麼一個對象,它有姓名,性別,年紀等多種屬性.可是咱們不想關心它的其餘信息,只想知道它的名字是啥.而它的其餘屬性值都不是像那些undefined
等同樣是無心義的值,咱們該如何過濾呢?
let obj = {
name:'zhangsan',
gender:'female',
age:18,
hobby:'swim'
}
console.log(JSON.stringify(obj,['age'])) // {"age":18}
複製代碼
這時,咱們的第2個參數就派上用場了.咱們傳入了一個數組,而這個數組中的值就是咱們想要保留的屬性名,不在這個數組之列的,所有都不要返回. 除了傳入數組類型之外,咱們還能夠傳入一個函數.
let obj = {
name:'zhangsan',
gender:undefined,
age:18,
hobby:'swim'
}
console.log(JSON.stringify(obj, (key, value) => {
if(typeof value === 'string'){
return undefined
}
return value
})) // {"age":18}
複製代碼
在函數中,咱們作了一些邏輯判斷,當屬性值是字符串的時候,就給它過濾掉.使用這第二個參數,咱們也能夠改變屬性值爲undefined
,symbol
之類的本來不會返回的屬性.
let obj = {
name:'zhangsan',
gender:undefined,
age:18,
hobby:'swim'
}
console.log(JSON.stringify(obj, (key, value) => {
if(typeof value === 'string'){
return undefined
}
if(typeof value === 'undefined'){
return 'not any more undefined'
}
return value
})) // {"gender":"not any more undefined","age":18}
複製代碼
再來結合toString()
這個方法,咱們來輸出函數的具體內容:
let obj = {
name:'zhangsan',
f:function(){
console.log('I\'m a function')
}
}
console.log(JSON.stringify(obj, (key, value) => {
if(typeof value === 'function'){
return Function.prototype.toString.call(value)
}
return value
}))
// {"name":"zhangsan","f":"function(){\n console.log('I\\'m a function')\n }"}
複製代碼
講完了第2個參數,咱們再來說講第3個參數.是的,你沒有看錯,它還有第三個參數.這個參數的主要做用是用來美化輸出的json字符串.在沒有第三個參數的時候,咱們輸出的字符串是擠在一堆的,不利於觀看.有了它,咱們就能夠格式化咱們的輸出結果:
let obj = {
name:'zhangsan',
age:18,
gender:'female'
}
console.log(JSON.stringify(obj,null,2))
/*{ "name": "zhangsan", "age": 18, "gender": "female" }*/
複製代碼
第三個參數傳入的類型是數字n的話,就表示每一級比它的上一級多縮進n個空格,n最大爲10 第三個參數傳入的類型是字符串的話,則會在每一級前面加上這個字符串,字符串的最大長度也是10
let obj = {
name:'zhangsan',
age:18,
gender:'female'
}
console.log(JSON.stringify(obj,null,'😊'))
/*{ 😊"name": "zhangsan", 😊"age": 18, 😊"gender": "female" }*/
複製代碼
總結: 至此,關於JSON.stringify()
的用法,咱們基本講的差很少了.大部分的知識點咱們就用下面的圖來表示了.