Fork me on GitHub

JSON.stringify多参数的应用(半译)

 不积跬步,无以至千里。

  JSON.stringify这个API相信JSer都不陌生。在我们进行数据本地持久化存储的时候就会使用它将一个数据体处理成JSON字符串存到storage内、另外大部分场景的后端返回数据体也是JSON串的格式。通常我们对这个API的印象就停留在传一个参数的情景,但实际上它可以接收多个参数XD。

第二个参数传回调函数

  先看一个例子:

1
2
3
4
5
6
7
8
9
const dude = {
name: "Pawel",
friends: ["Dan", "Pedro", "Mr Gregory"]
};
const dudeStringified = JSON.stringify(dude);

console.log(dudeStringified);

// {"name":"Pawel","friends":["Dan","Pedro","Mr Gregory"]}

  没什么毛病,这也是我们开头说的被使用最多的一种场景。

特殊类型的处理

  再往下看:

1
2
3
4
5
6
7
8
9
const dude = {
name: "Pawel",
friends: new Set(["Dan", "Pedro", "Mr Gregory"])
};
const dudeStringified = JSON.stringify(dude);

console.log(dudeStringified);

// {"name":"Pawel","friends":{}}

  此时,内部是一个Set结构了,这种结构在进行序列化时,会被忽略或者处理为null。同等情况的还有WeakSetMapWeakMap

  有没有什么办法可以额外处理呢?有的,就是在第二个参数传一个回调函数进去,这个回调支持两个参数分别对应原序列化对象的keyvalue

  我们可以像下面这样处理,通过instanceof判断传入value是由Set构造的实例,同时借助内部的iterator进行解构转成数组。

1
2
3
4
5
6
7
8
9
10
const dude = {
name: "Pawel",
friends: new Set(["Dan", "Dan", "Pedro", "Mr Gregory"])
};
const dudeStringified = JSON.stringify(dude, (key, value) =>
value instanceof Set ? [...value] : value
);

console.log(dudeStringified);
// {"name":"Pawel","friends":["Dan","Pedro","Mr Gregory"]}

定制替换内容

1
2
3
4
5
6
7
8
9
10
11
// Second argument as a replacer function

const dude = {
name: "Dan"
};
const dudeStringified = JSON.stringify(dude, (key, value) =>
key === "name" ? "Pawel" : value
);

console.log(dudeStringified);
// {"name":"Pawel"}

第二个参数传数组

设置白名单(过滤key)

  这种场景与上面不太一样,第二个参数会传一个数组,内容是我们要保留的对象的key属性。

1
2
3
4
5
6
7
8
9
10
11
// Second argument as an array of white-listed keywords

const dude = {
name: "Pawel",
friends: new Set(["Dan", "Pedro", "Mr Gregory"])
};

const dudeStringified = JSON.stringify(dude, ["name"]);

console.log(dudeStringified);
// {"name":"Pawel"}

第三个参数的分隔符作用

  实际效果有点像格式化后填充缩进,填充内容取决于第三个参数。

  当参数为number类型时,返回的序列将按照该number数值的大小进行空格格式化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Third argument as a number

const dude = {
name: "Pawel",
friends: ["Dan", "Pedro", "Mr Gregory"]
};
const dudeStringified = JSON.stringify(dude, null, 4);

console.log(dudeStringified);
// {
// "name": "Pawel",
// "friends": [
// "Dan",
// "Pedro",
// "Mr Gregory"
// ]
// }

  当参数为string类型时,返回的序列将以该string内容进行格式化填充。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Third argument as a string

const dude = {
name: "Pawel",
friends: ["Dan", "Pedro", "Mr Gregory"]
};
const dudeStringified = JSON.stringify(dude, null, "🍆");

console.log(dudeStringified);
// {
// 🍆"name": "Pawel",
// 🍆"friends": [
// 🍆🍆"Dan",
// 🍆🍆"Pedro",
// 🍆🍆"Mr Gregory"
// 🍆]
// }