JS中JSON.stringify序列化和JSON.parse反序列化问题和解决

网友投稿 423 2022-08-23

JS中JSON.stringify序列化和JSON.parse反序列化问题和解决

当我们想把对象转为JSON串的时候,肯定会想到JSON.stringify;还一种情况,当我们想实现一个深拷贝的时候,也会想到JSON.parse(JSON.stringify());但其实JSON.stringify序列化是有些问题的。先给大家举个例子:

现在有个对象,通过JSON.stringify转一下如下:

转完之后我们发现,函数和值为undefined的属性都丢失了,值为NaN的转为了null ,这就是存在的问题,当我们想实现一个深拷贝的时候,如果对象中没有函数或者undefined或者上面的问题不影响我们的使用,自然是可以通过这种方式的,又方便,谁不愿意用呢。但如果上面的问题有影响到我们正常使用,或者我们就想保留上面的属性,那就不能使用JSON这种方式,可以手写一个深拷贝来实现,可以去看下我之前的一篇博文:《​​js深拷贝​​》

出现上面的原因是因为:

使用JSON.Stringify 转换的数据中,如果包含 function,undefined,Symbol,这几种类型,不可枚举属性,JSON.Stringify序列化后,这个键值对会消失。转换的数据中包含 NaN,Infinity 值(含-Infinity),JSON序列化后的结果会是null。转换的数据中包含Date对象,JSON.Stringify序列化之后,会变成字符串。转换的数据包含RegExp 引用类型序列化之后会变成空对象。无法序列化不可枚举属性。无法序列化对象的循环引用,(例如: obj[key] = obj)。无法序列化对象的原型链。

JSON.stringify自然好用,但是也要避免上面的问题

针对上面的问题,我想看下能不能解决,然后自己试着写了一下,当然也找了一些关于JSON的方法、参数等资料,重新写了两个方法(算是对stringify和parse方法进行了扩展吧) 如下:

// JSON.stringify对象序列化,解决undefined、函数和NaN 丢失问题function JSONStringify(option) { return JSON.stringify(option, (key, val) => { // 处理函数丢失问题 if (typeof val === 'function') { return `${val}`; } // 处理undefined丢失问题 if (typeof val === 'undefined') { return 'undefined'; } // 处理NaN转为null的情况(注意: 这里如果使用isNaN的话,那么对象也会走进去) if (val !== val) { return `${val}` } return val; }, 2)}// JSON.parse 反序列化function JSONParse(jsonStr) { const retain = ['function', 'undefined', 'NaN'] return JSON.parse(jsonStr, (key, val) => { // eval 可能在eslint中报错,需要加入下行注释 // eslint-disable-next-line if (typeof val === 'string' && retain.some(s => val.indexOf(s) >= 0)) { return eval(`(function(){return ${val}})()`); } return val })}

然后使用这两个方法再试一下

console.log(JSONStringify(o), 'stringify序列化处理----->>>')console.log(JSONParse(JSONStringify(o)), 'parse解析序列化处理----->>>')

打印如下:

开始我以为万事大吉了,但是仔细一看,序列化确实没有问题的,全部保留了,但是解析的时候我的undefined还是没了,undefined和函数、NaN一样处理的,因为一个函数没有返回值的话,默认返回的就是undefined,现在我们让它返回一个undefined,但是没出来呢,也可能是JSON.parse确实转不了undefined,目前还没找到答案,先这样吧,至少比之前好多了。

深拷贝的时候如果不考虑undefined,基本上直接可以用上面的两个方法了,还是蛮方便的,当然手写一个深拷贝的工具方法也方便,看自己喜好吧。注意:上面两个方法相互结合、相互使用

最后再补充一下,上面有用到eval函数,这是原生js一个函数,可以直接使用,可以参考一位博友的文章:​​浅谈JS中的 eval函数​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:什么是 Office Open XML 文件格式
下一篇:python实现redis三种cas事务操作
相关文章

 发表评论

暂时没有评论,来抢沙发吧~