JSON.stringify在转换中忽略其值未定义undefined的字段

今天使用JSON时,发现了一个小问题,及时修复了,记录一下。然后自己又重新学习了JSON.stringify,发现其还有很多平时没有注意的特性。

 

发现问题

用户提交的表单,如果数据完整,那么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"}]'

但是当用户提交的数据不完整时,数据会变成这样:

[
  {
    fieldId: 539,
    value: undefined
  },
  {
    fieldId: 540,
    value: undefined
  },
  {
    fieldId: 546,
    value: undefined
  },
]

然后会变成这样:

'[{"fieldId":539},{"fieldId":540},{"fieldId":546}]'

当这个数据被发送到后端时,后端如果没处理好,就会导致错误,因为缺少了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这个内置函数的一些特点。

基本上, JSON.stringify 将对象转换为 JSON 字符串。

 

同时,JSON.stringify 有以下规则。

1、undefinedFunctionSymbol不是有效的 JSON 值。

如果在转换过程中遇到任何此类值,则它们要么被忽略(在对象中找到时),要么被更改为null(在数组中找到时)。JSON.stringify()可以在传入“纯”值(如JSON.stringify(function() {})JSON.stringify(undefined) )时返回undefined

console.log(JSON.stringify(
{
    name: Symbol('卡卡测速网'),
    value: undefined,
    showName: () =>
    {}
}))

上述语句的执行结果是返回undefined

2、Boolean, Number和String对象在字符串化过程中被转换为对应的原始值,符合传统的转换语义。 

 

3、所有Symbol带键的属性都将被完全忽略,即使在使用replacer函数时也是如此。

 

4、数字InfinityNaN以及null都被认为null

 

5、如果值有toJSON()方法,它负责定义哪些数据将被序列化。

 

6、实例通过返回字符串来Date实现toJSON()功能(同date.toISOString())。因此,它们被视为字符串。

const d = new Date();
console.log(d.toJSON());
console.log(JSON.stringify(d));

执行结果

 

总结

因为一个bug,我今天重新学习了JSON.stringify,发现它还有很多平时没有注意到的特性。同时也希望大家以后不要犯同样的错误。

您可能对以下文章也感兴趣

  • 用JSON.stringify()转换字符串时加过滤函数只保留数值项
  • 15个JSON.stringify()参考示例
  • 详解JSON.stringify()与JSON.parse()转换JSON对象和字符串
  • 两种方法Javascript访问JSON(含嵌套)数据
  • 介绍两种方法JS读取 .JSON 文件【实例演示/源码下载】
  • 表单序列化插件serializeJSON.js下载及使用示例
  • JQuery如何把JSON字符串转为JSON对象