首页 > 其他分享 >#yyds干货盘点#慎用JSON.stringfy

#yyds干货盘点#慎用JSON.stringfy

时间:2022-10-08 20:32:12浏览次数:40  
标签:yyds stringify name age value JSON stringfy like

项目中遇到一个 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,stringify,name,age,value,JSON,stringfy,like
From: https://blog.51cto.com/u_11365839/5738646

相关文章

  • JSON语法格式
    javascript作用:改变HTML内容JavaScript内嵌于HTML网页中,通过浏览器内置的JavaScript引擎进行解释执行,把一个原本只用来显示的页面转变成支持用户交互的页面程序。Javascr......
  • net中c#教程 Json字符串的常用操作
    json字符串格式的出现,大大地方便了不同系统间的数据传输,无论是Net项目还是Java项目都适用。今天就分享几个json的常用操作。我们是基于Newtonsoft.Json这个第三方类库实现......
  • Collecting package metadata (current_repodata.json): failed--2个解决方案
    问题描述:在​​cmd.exe​​​中新建​​Python​​​环境,报错​​Collectingpackagemetadata(current_repodata.json):failed​​报错界面寻找问题所在重装过anaconda,在......
  • json各种操作
    String转Json判断字符串是否可以转化为json对象JSONObject /***判断字符串是否可以转化为json对象*@paramcontent*@return*/publicst......
  • Json字符串转换处理html编码格式,= \u003d 处理
    Json字符串转换处理html编码格式,= \u003d处理importcom.alibaba.fastjson.annotation.JSONField;importcom.fasterxml.jackson.annotation.JsonAutoDetect;import......
  • postman请求,修改Headers中Accept参数为application/json,使返回json格式的数据
    设置之前:  设置之后:  参考:https://blog.csdn.net/qq_40931553/article/details/108465580 ......
  • 浅析package.json 和 package-lock.json的区别
    一package.json中的版本符号{"react":"^18.2.0","react-dom":"~18.2.0""react-refresh":"0.11.0",}插入符号^18.2.0:匹配18.X.X的最新版本。波浪符号~1......
  • 如何理解package.json中的proxy字段?
    入职新公司以来,第一个月接手vue项目,第二个月接手angularjs项目,第三个月加入react重构项目。心生感叹:业务驱动式学习是一种高效率的学习方式,保持好奇心,在业务中快速成长!新项......
  • 深入理解JSON.stringify()
    就我目前4年(实习了1年,965了1年,996了2年,算3年感觉少了,说是4年老司机也不为过吧。)的工作经验来看,JSON.stringify一般有以下用途:深拷贝:深拷贝引用类型的数据序列化:服务端存储......
  • tsconfig.json的esModuleInterop使用场景是怎样的?
    问题场景npm包改造前,仅支持esmnpm包改造后,既支持esm,又支持cjs为什么改造后,还是会报错?如何理解ts编译配置esModuleInterop?总结问题场景遇到一个很有趣的场景,cjs中需要引入原......