#yyds干货盘点#慎用JSON.stringfy
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#慎用JSON.stringfy相关的知识,希望对你有一定的参考价值。
项目中遇到一个 bug,一个组件为了保留一份 JSON 对象,使用 JSON.stringify 将其转换成字符串,这样做当然是为了避免对象是引用类型造成数据源的污染。
但发现后面使用 JSON.parse 方法之后,发现数据有所变化。
代码简化:
let obj =
name: Gopal,
age: Infinity
let originObj = JSON.stringify(obj)
console.log(originObj) // "name":"Gopal","age":null
可以看到,Infinity 变成了 null,从而导致了后面的 bug。其实项目中自己踩 JSON.stringify 的坑已经很多了,借此机会好好整理一下,也给大家一个参考。
先说下这个问题的解决方法:
解决方法1:
简单粗暴,重新给 age 属性赋值
解决方法2:
function censor(key, value)
if (value === Infinity)
return "Infinity";
return value;
var b = JSON.stringify(a, censor);
var c = JSON.parse(
b,
function (key, value)
return value === "Infinity" ? Infinity : value;
);
这就有点绕了,当做参考吧,其实我自己是直接使用了第一种方法。不过这里可以看到 JSON.stringify 实际上还有第二个参数,那它有什么用呢?接下来我们揭开它的神秘面纱。
JSON.stringify 基础语法
JSON.stringify(value[, replacer [, space]])
概念
MDN 中文文档对它的解释如下:
JSON.stringify() 方法将一个 javascript 值(对象或者数组)转换为一个 JSON 字符串,如果指定了 replacer 是一个函数,则可以选择性地替换值,或者如果指定了 replacer 是一个数组,则可选择性地仅包含数组指定的属性。
我个人觉得这样解释是有所不妥的,不妥之处在于“对象或者数组”,因为实际上对于普通的值,我们也可以使用 JSON.stringify,只是我们很少这么用罢了。不过这个问题不大,我们文中介绍的也都是针对对象或者数组。
JSON.stringify(foo); // "foo"
而英文版 MDN 的解释就会合理很多:
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
简单来说,JSON.stringify() 就是将值转换为相应的 JSON 格式字符串。
JSON.stringify 强大的第二个参数 replacer
这个参数是可选的,可以是一个函数,也可以是一个数组
当是一个函数的时候,则在序列化的过程中,被序列化的每个属性都会经过该函数的转换和处理,看如下代码:
let replacerFun = function (key, value)
console.log(key, value)
if (key === name)
return undefined
return value
let myIntro =
name: Gopal,
age: 25,
like: FE
console.log(JSON.stringify(myIntro, replacerFun))
// "age":25,"like":"FE"
这里其实就是一个筛选的作用,利用的是 JSON.stringify 中对象属性值为 undefined 就会在序列化中被忽略的特性(后面我们会提到)。
值得注意的是,在一开始 replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象。
上面 console.log(key, value) 输出的值如下:
name: Gopal, age: 25, like: FE
name Gopal
age 25
like FE
"age":25,"like":"FE"
可以看出,通过第二个参数,我们可以更加灵活的去操作和修改被序列化目标的值。
当第二个参数为数组的时候,只有包含在这个数组中的属性名才会被序列化:
JSON.stringify(myIntro, [name]) // "name":"Gopal"
中看不中用的第三个参数
指定缩进用的空白字符串,更多时候就是指定一个数字,代表几个空格:
let myIntro =
name: Gopal,
age: 25,
like: FE
console.log(JSON.stringify(myIntro))
console.log(JSON.stringify(myIntro, null, 2))
// "name":"Gopal","age":25,"like":"FE"
//
// "name": "Gopal",
// "age": 25,
// "like": "FE"
//
JSON.stringify 使用场景
判断对象/数组值是否相等
let a = [1,2,3],
b = [1,2,3];
JSON.stringify(a) === JSON.stringify(b);// true
localStorage/sessionStorage 存储对象
我们知道 localStorage/sessionStorage 只可以存储字符串,当我们想存储对象的时候,需要使用 JSON.stringify 转换成字符串,获取的时候再 JSON.parse。
// 存
function setLocalStorage(key,val)
window.localStorage.setItem(key, JSON.stringify(val));
;
// 取
function getLocalStorage(key)
let val = JSON.parse(window.localStorage.getItem(key));
return val;
;
实现对象深拷贝
let myIntro =
name: Gopal,
age: 25,
like: FE
function deepClone()
return JSON.parse(JSON.stringify(myIntro))
let copyMe = deepClone(myIntro)
copyMe.like = Fitness
console.log(myIntro, copyMe)
// name: Gopal, age: 25, like: FE name: Gopal, age: 25, like: Fitness
路由(浏览器地址)传参
因为浏览器传参只能通过字符串进行,所以也是需要用到 JSON.stringify。
以上是关于#yyds干货盘点#慎用JSON.stringfy的主要内容,如果未能解决你的问题,请参考以下文章