还不知道JSON.stringify6大问题及3个参数正确使用方式?

177 阅读3分钟

背景

很多同学可能只知道JSON.stringify是将数据序列化,变为JSON字符串的,但不知其有很多坑,也不知其还有两外两个参数

本文目的

1,JSON.stringify作用

2,JSON.stringify6种问题

3,JSON.stringify方法三个参数

JSON.stringify作用

先说一下JSON.stringify() 方法作用:用于将 JavaScript 值转换为 JSON 字符串。

正文

JSON.stringify问题清单

1,Date 日期调用了 toJSON() 将其转换为了 string 字符串。

2,对象中有undefined和Function类型数据的时候,序列化之后会直接丢失。

3,对象中有NaN、Infinity和-Infinity的时候,序列化之后会显示null。

4,对象循环引用的时候,会直接报错。

5,以 symbol 为属性键的属性都会被完全忽略掉

6,只可序列化可枚举的属性

下面我们依次来讲清楚这6个问题

1,Date 日期调用了 toJSON() 将其转换为了 string 字符串

const obj = {
    date:new Date()
}
typeof obj.date // object
const objCopy = JSON.parse(JSON.stringify(obj));
console.log(objCopy.date) // 2022-07-16T08:47:13.753Z

然后关于Date对象的方法都会用不了,getTime、getMonth等啥都没了,因为已经变为了字符串。

2,对象中有undefined和Function类型数据的时候,序列化之后会直接丢失

不多说,直接上代码

const obj = {
  name: undefined,
  sayName: () => { console.log('hhh') }
}
const objCopy = JSON.parse(JSON.stringify(obj));
console.log('objCopy:', objCopy) // {}

这里是浏览器运行截图

3,对象中有NaN、Infinity和-Infinity的时候,序列化之后会显示null

老规矩,看代码

const obj = {
  NaN:NaN,
  InfinityMax:Infinity,
  InfinityMin:-Infinity,
}
console.log(obj, "obj"); // {NaN: NaN, InfinityMax: Infinity, InfinityMin: -Infinity} 'obj'
const objCopy = JSON.parse(JSON.stringify(obj));
console.log(objCopy,"objCopy") // {NaN: null, InfinityMax: null, InfinityMin: null} 'objCopy'

浏览器运行截图

怎么样,是不是已经难以想象有这么严重的问题了

4,对象循环引用的时候,会直接报错

const obj = {}
obj.aaa = obj;
const objCopy = JSON.parse(JSON.stringify(obj)); // 这里直接报错:Uncaught TypeError: Converting circular structure to JSON--> starting at object with constructor 'Object'--- property 'aaa' closes the circleat JSON.stringify
console.log("objCopy:", objCopy)

下面时报错截图

5,以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们

JSON.stringify({[Symbol("foo")]: "foo"}); // '{}'
JSON.stringify(
    {[Symbol.for("foo")]: "foo"},
    function (k, v) {
        if (typeof k === "symbol"){
            return "a symbol";
        }
    }
); // undefined

6,只可序列化可枚举的属性,包括 Map/Set/WeakMap/WeakSet

// 不可枚举的属性默认会被忽略:
JSON.stringify(
    Object.create(
        null,
        {
            x: { value: 'x', enumerable: false },
            y: { value: 'y', enumerable: true }
        }
    )
);
// "{"y":"y"}"

现在大家对JSON.stringify的几个问题应该都清楚了吧

JSON.stringify3个参数

JSON.stringify(value, ?replacer, ?space)

1,value:将要序列化成 一个 JSON 字符串的值。

2,?replacer:?代表可选,如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。

3,?space:指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。

const obj = {
  name:"aaa",
  age: 18
}

第二个参数?replace

?replace为数组时

?replace为函数时

?replace为函数时,所有属性都会经过此函数的过滤

第三个参数?space

此参数时为了美化输出,有两种使用方式,数字或者字符

传入数字

传入指定字符

参考文档

MDN:developer.mozilla.org/zh-CN/docs/…