前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你不知道的JSON.stringify

你不知道的JSON.stringify

作者头像
前端黑板报
发布2020-05-19 09:37:25
9020
发布2020-05-19 09:37:25
举报
文章被收录于专栏:前端黑板报前端黑板报

点击上方蓝色字体,关注我们

最近使用 Vue 写后台管理系统,在做 Tab 组件的持久化时遇到一个问题:

代码语言:txt
复制
localStorage.setItem('tabs',JSON.stringify(tabs))

上面代码报错:

看意思应该是产生了循环引用的结构,下面是不同浏览器对于这个类型错误报出错的形式:

代码语言:txt
复制
TypeError: cyclic object value (Firefox)
TypeError: Converting circular structure to JSON (Chrome and Opera)
TypeError: Circular reference in value argument not supported (Edge)

举个例子?:

代码语言:txt
复制
var circularReference = {otherData: 123};
circularReference.myself = circularReference;

此时到控制台里面运行一下:

代码语言:txt
复制
JSON.stringify(circularReference);

// 报错信息如下
VM685:1 Uncaught TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    --- property 'myself' closes the circle
    at JSON.stringify ()
    at:1:6

可以看到和我上面说的 Vue 的例子是类似的。

那如何解决呢?

既然是由于循环引用导致的,那我们可以在发生循环引用的地方给切断。

那如何切断呢?

幸好 JSON.stringify 方法提供了便利,语法如下:

代码语言:txt
复制
JSON.stringify(value[, replacer[, space]])

replacer 可以作为一个函数传入,且接受 key 和 value 作为入参,如下:

代码语言:txt
复制
JSON.stringiify({},function(key,value){
    // do sth
})

那解决方案就有啦:

代码语言:txt
复制
JSON.stringify(circularReference,function(key,value){
    if(key == 'myself'){ // 这里的key的判断条件,就是上面报错信息里的 property 'xxx' closes the circle,这里xxx是什么条件就是什么
        return 
    }
    return value
})

每次需要定位 key 值,如果嫌麻烦还有更简便的方法:

代码语言:txt
复制
const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    return value;
  };
}

推荐几个解决类似问题的库:

  • circular-json (只维护,vue-devtools 内部也使用它)
  • flatted (上面的继承者)
  • json-stringify-safe
  • cycle.js
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端黑板报 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档