|
|
|
|
|
今天使用JSON時,發(fā)現(xiàn)了一個小問題,及時修復了,記錄一下。然后自己又重新學習了JSON.stringify
,發(fā)現(xiàn)其還有很多平時沒有注意的特性。
發(fā)現(xiàn)問題
用戶提交的表單,如果數(shù)據(jù)完整,那么JSON是這樣:
[
{
"fieldId": 539,
"value": "silver card"
},
{
"fieldId": 540,
"value": "2021-03-01"
},
{
"fieldId": 546,
"value": "10:30"
}
]
然后會變成這樣:
'[{"fieldId":539,"value":"silver card"},{"fieldId":540,"value":"2021-03-01"},{"fieldId":546,"value":"10:30"}]'
但是當用戶提交的數(shù)據(jù)不完整時,數(shù)據(jù)會變成這樣:
[
{
fieldId: 539,
value: undefined
},
{
fieldId: 540,
value: undefined
},
{
fieldId: 546,
value: undefined
},
]
然后會變成這樣:
'[{"fieldId":539},{"fieldId":540},{"fieldId":546}]'
當這個數(shù)據(jù)被發(fā)送到后端時,后端如果沒處理好,就會導致錯誤,因為缺少了value屬性。
解決問題
這是因為,JSON.stringify
在轉換過程中忽略其值未定義的字段。
問題的原因找到了,解決方法也很簡單,將值為undefined
的項轉為空字符串提交即可。
let signInfo = [
{
fieldId: 539,
value: undefined
},
{
fieldId: 540,
value: undefined
},
{
fieldId: 546,
value: undefined
},
]
let newSignInfo = signInfo.map((it) => {
const value = typeof it.value === 'undefined' ? '' : it.value
return {
...it,
value
}
})
console.log(JSON.stringify(newSignInfo))
// '[{"fieldId":539,"value":""},{"fieldId":540,"value":""},{"fieldId":546,"value":""}]'
了解JSON.stringify
接下來我們來分析一下JSON.stringify
這個內置函數(shù)的一些特點。
基本上, JSON.stringify
將對象轉換為 JSON 字符串。
同時,JSON.stringify
有以下規(guī)則。
1、undefined
、Function
和Symbol
不是有效的 JSON 值。
如果在轉換過程中遇到任何此類值,則它們要么被忽略(在對象中找到時),要么被更改為null
(在數(shù)組中找到時)。JSON.stringify()
可以在傳入“純”值(如JSON.stringify(function() {})
或JSON.stringify(undefined)
)時返回undefined
。
console.log(JSON.stringify(
{
name: Symbol('卡卡測速網'),
value: undefined,
showName: () =>
{}
}))
上述語句的執(zhí)行結果是返回undefined
:
2、Boolean, Number和String對象在字符串化過程中被轉換為對應的原始值,符合傳統(tǒng)的轉換語義。
3、所有Symbol
帶鍵的屬性都將被完全忽略,即使在使用replacer
函數(shù)時也是如此。
4、數(shù)字Infinity
和NaN
以及null
都被認為null
。
5、如果值有toJSON()
方法,它負責定義哪些數(shù)據(jù)將被序列化。
6、實例通過返回字符串來Date
實現(xiàn)toJSON()
功能(同date.toISOString()
)。因此,它們被視為字符串。
const d = new Date();
console.log(d.toJSON());
console.log(JSON.stringify(d));
執(zhí)行結果
總結
因為一個bug,我今天重新學習了JSON.stringify
,發(fā)現(xiàn)它還有很多平時沒有注意到的特性。同時也希望大家以后不要犯同樣的錯誤。