• 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方法进行了扩展吧) 如下:

    1. // JSON.stringify对象序列化,解决undefined、函数和NaN 丢失问题
    2. function JSONStringify(option) {
    3. return JSON.stringify(option, (key, val) => {
    4. // 处理函数丢失问题
    5. if (typeof val === 'function') {
    6. return `${val}`;
    7. }
    8. // 处理undefined丢失问题
    9. if (typeof val === 'undefined') {
    10. return 'undefined';
    11. }
    12. // 处理NaN转为null的情况(注意: 这里如果使用isNaN的话,那么对象也会走进去)
    13. if (val !== val) {
    14. return `${val}`
    15. }
    16. return val;
    17. }, 2)
    18. }
    19. // JSON.parse 反序列化
    20. function JSONParse(jsonStr) {
    21. const retain = ['function', 'undefined', 'NaN']
    22. return JSON.parse(jsonStr, (key, val) => {
    23. // eval 可能在eslint中报错,需要加入下行注释
    24. // eslint-disable-next-line
    25. if (typeof val === 'string' && retain.some(s => val.indexOf(s) >= 0)) {
    26. return eval(`(function(){return ${val}})()`);
    27. }
    28. return val
    29. })
    30. }

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

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

    打印如下: 

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

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

    注意:上面两个方法相互结合、相互使用

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

  • 相关阅读:
    HTML常用基本元素总结
    两个pdf文件合并为一个怎么操作?分享pdf合并操作步骤
    【论文系列】01_如何做好文献阅读及笔记整理
    Java项目防止SQL注入的四种方案
    数据结构之红黑树
    WebRTC 源码 编译 iOS端
    Java的JDBC编程
    不相交的线
    Cesium 地球(1)-概览
    驱动开发5 阻塞IO实例、IO多路复用
  • 原文地址:https://blog.csdn.net/m0_51431448/article/details/126254585