JSON.stringify的问题

在js中提到对象转JSON字符串,基本都会想到JSON.stringify这个方法,以及对应的解析方法JSON.parse方法,这个的转换也被不少人用于深拷贝的操作中。
但是随着这一对方法的使用,我们会发现它们存在的弊端,比如会丢失函数和undefined类型的内容,如下:在这里插入图片描述
这里边的丢失内容为undefined类型c和函数f,在查询了资料后发现JSON.stringify会丢失的内容有以下内容:

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

这样看来JSON.stringify简单好用,但是在使用上就要避免以上的问题了

JSON.stringify问题解决

在小编的工作中遇到较多的是函数丢失问题,因此在自己的项目会对JSON.stringify进行进一步的改造,也是基于JSON.stringigy提供的方式来的,使用起来没有什么差别,如下:

// 对象序列化,undefined和函数丢失问题
const JSONStringify = (option) => {
  return JSON.stringify(option,
    (key, val) => {
      // 处理函数丢失问题
      if (typeof val === 'function') {
        return `${val}`;
      }
      // 处理undefined丢失问题
      if (typeof val === 'undefined') {
        return 'undefined';
      }
      return val;
    },
    2
  )
}
// 对象序列化解析
const JSONParse = (objStr) => {
  return JSON.parse(objStr, (k, v) => {
    if (typeof v === 'string' && v.indexOf && v.indexOf('function') > -1) {
      // eval 可能在eslint中报错,需要加入下行注释
      // eslint-disable-next-line
      return eval(`(function(){return ${v}})()`);
    }
    return v;
  });
}

const obj = {
  a: null,
  b: 1,
  c: undefined,
  d: 'aaaa',
  e: true,
  f () {
    console.log('内容');
  }
}
// 序列化处理
const JSONStr = JSONStringify(obj);
console.log('序列化处理', JSONStr);
// 序列化解析
const JSONObj = JSONParse(JSONStr);
console.log('解析序列化内容', JSONObj);

// 深拷贝使用
const obj2 = JSONParse(JSONStringify(obj));
console.log('当前obj内容: ', obj);

上边内容输出的结果为:
在这里插入图片描述
这样简单改造后就支持了携带函数和undefined进行转换了,其它的问题也可以用相似的问题处理,这里就不一一介绍了

JSON.stringify深拷贝

对于深拷贝比较通俗的讲法就是将一个变量赋值给另一个变量,修改时候互不影响。
在js中最简单的方式就是JSON.stringify的方式了,但是处于上边描述的问题,很多人就采用了其它方式了比如函数递归等方式了,不过使用上边对JSON.stringify​封装的方式就可以了。
对于深拷贝这里只是一笔带过,如有疑问可以到技术群进行交流,文章底部有入群方式。


以上就是本文全部内容,如对你有帮助欢迎点赞留言
如有疑问可以留言,也可以到QQ群一起探讨:
QQ群1: 657011407, QQ群2: 492593055,也可以到微信找我 shenzhipeng1023(如要加微信群告诉小编即可)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐