目录

思考

JSON.stringify() 的作用

JSON.stringify() 的规则

答案


思考

以下代码执行结果是什么?

let list = [
  {
    name: 'leo',
    age: 18,
    like: undefined
  },
  {
    name: 'lion',
    age: 25,
    like: undefined
  }
]
console.log(JSON.stringify(list),'***JSON.stringify***')

带着疑问,一步步彻底了解 JSON.stringify()。(答案在文章末尾)

JSON.stringify() 的作用

JSON.stringify() 可以将 JavaScript 对象或值转换为 JSON 字符串(也称序列化)。

例:

console.log(typeof {name:'leo',age:18})   // object
console.log(typeof JSON.stringify({name:'leo',age:18}))   // string

console.log(JSON.stringify({name:'leo',age:18}))   // '{"name":"leo","age":18}'

但是,JSON.stringify() 有几点需要注意的地方,我们需要了解其使用规则,避免出现bug。

JSON.stringify() 的规则

1、如果目标对象存在 toJSON(),它负责定义哪些数据将被序列化

let obj = {
  name: 'leo',
  age: 18,
  toJSON: function(){
    return '我是被序列化的部分'
  }
}
console.log(JSON.stringify(obj))   // '我是被序列化的部分'

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

let obj = {
  name: new String('leo'),
  age: new Number(18),
  like: new Boolean(true)
}
console.log(JSON.stringify(obj))   // '{"name":"leo","age":18,"like":true}'

3、undefined、Function 和 Symbol 不是有效的 JSON 值。如果在转换过程中遇到任何此类值,则它们要么被忽略(在对象中),要么被更改为 null(当在数组中

(1)对象

let obj = {
  name: Symbol('leo'),
  age: undefined,
  like: function(){}
}
console.log(JSON.stringify(obj))   // {}
// 对象被序列化,undefined、Symbol、Function 忽略

(2)数组 

let arr = [Symbol('leo'), undefined, function(){}, 'lion']
console.log(JSON.stringify(arr))   // '[null,null,null,"lion"]'
// 数组被序列化,undefined、Symbol、Function 更改为 null

4、所有 Symbol - key 属性将被完全忽略

let obj = {
  [Symbol('name')]: 'leo',
  [Symbol('age')]: 18
}
console.log(obj)   // {Symbol(name): 'leo', Symbol(age): 18}  [[Prototype]]: Object
console.log(JSON.stringify(obj))   // {}

5、Date 的实例通过返回一个字符串来实现 toJSON()(与 date.toISOString() 相同)。因此,它们被视为字符串

console.log(new Date().toISOString())   // "2022-07-13T12:59:35.074Z"
console.log(JSON.stringify(new Date()))   // "2022-07-13T12:59:35.074Z"

6、数字 Infinity 和 NaN 以及 null 值都被认为是 null

let obj = {
  num1: Infinity,
  num2: NaN,
  num3: null,
  num4: 18
}
console.log(JSON.stringify(obj))   // '{"num1":null,"num2":null,"num3":null,"num4":18}'

7、所有其他 Object 实例(包括 Map、Set、WeakMap 和 WeakSet)仅序列化其可枚举的属性

let obj = {}
Object.defineProperties(obj,{
  name: {
    value: 'leo',
    enumerable: true
  },
  age: {
    value: 18,
    enumerable: false   // 不可枚举属性
  }
})
console.log(JSON.stringify(obj))   // '{"name":"leo"}'

8、找到循环引用时抛出 TypeError(“循环对象值”)异常

let obj = {
  name: 'leo',
  age: 18
}
obj.children = obj
console.log(JSON.stringify(obj))

下班前几分钟,我彻底弄懂了JSON.stringify()-LMLPHP

9、尝试对 BigInt 值进行序列化时抛出 TypeError(“BigInt 值无法在 JSON 中序列化”)

let obj = {
  age: BigInt(84373859483925178759)
}
console.log(JSON.stringify(obj))

下班前几分钟,我彻底弄懂了JSON.stringify()-LMLPHP

答案

花几分钟,掌握这9条规则,让自己学会灵活使用 JSON.stringify()。

so,上面的思考题,你知道执行结果是什么了吗?

07-14 14:34