哇塞,有好吃的~

JSON.stringify()的几个场景

循环引用

使用JSON.stringify()时,遇到循环引用的时候,会抛出错误TypeError: Converting circular structure to JSON,如果需要强行转成字符串的话,需要利用到该方法的第二个参数。

主要思路其实就是将循环引用的部分替换成某个标识,等到解析的时候去替换掉,就可以拿到原来的循环引用的对象。通常是为了在输出json文件后,依然可以得到原来的循环引用的对象来处理。在此也就是抛砖引玉,不做更多的探讨,下面的实现肯定有遗漏的地方,主要就是记录一下思路。

// 先讲环的部分按照自己的格式存起来,并且记录环指向的对象 const JSONStringify = (obj) => { const cache = new Map(); // 额外套一层,就是为了防止循环引用的是最外层的对象,无法去记录对应的key值 const newObj = { entry: obj }; return JSON.stringify(newObj, (key, value) => { if(typeof value === 'object' && value !== null) { if(cache.has(value)) { return `[[object_${cache.get(value)}]]`; } cache.set(value, key); } return value; }) }; // 用来专门解析上面产生的字符串 const JSONParse = (objStr) => { const parseObj = JSON.parse(objStr); let cache = {}; const ergodic = (obj) => { for(const [key, value] of Object.entries(obj)) { // 匹配到了环的部分就去替换 if(/\[\[object_\w+\]\]/.test(value)) { const [,circleKey] = value.slice(2, -2).split('_'); obj[key] = cache[circleKey]; } // 记录所有的对象 if(typeof value === 'object' && value !== null) { cache[key] = value; ergodic(value); } } }; ergodic(parseObj); return parseObj.entry; }; const obj = { a: { b: 1 } }; obj.a.c = obj; const objStr = JSONStringify(obj); // {"entry":{"a":{"b":1,"c":"[[Object_entry]]"}}} const newObj = JSONParse(objStr); // { a: { b: 1, c: [Circular *1] } }

大JSON的处理

当 JSON.stringify 所生成的字符串长度超过了一定大小的限制后,会抛出Uncaught RangeError: Invalid string length错误。

我自己的思路大概有两个,一个是拆开去转化,另一个就是使用数据流的形式去读写,目前用第一种方式也能满足我的场景。正常来说,拆开就可以防止一次的JSON.stringify占据的内存过大,如果拆开一层还不行,可以试试递归几次应该就满足了。

const bigJSONStringify = (obj) => { let result = ''; if(Array.isArray(obj)) { result += '['; for(let value of obj) { if(typeof value === 'object' && value !== null) { result += JSON.stringify(value); } else { result += value; } result += ',' } result = result.slice(0, -1) + ']'; } else { result += '{'; for(const [key, value] of Object.entries(obj)) { if(typeof value === 'object' && value !== null) { result += `"${key}": ${JSON.stringify(value)}`; } else { // 字符串类型加双引号 result += `"${key}": ${typeof value === 'string' ? `"${value}"` : value}`; } result += ',' } result = result.slice(0, -1) + '}'; } return result; }; bigJSONStringify([{ a: 'a', v:2, d: { m: 3}}, 2, { c: 1, d: 3 }]) // [{"a":"a","v":2,"d":{"m":3}},2,{"c":1,"d":3}] bigJSONStringify({ a: 'a', v:2, d: { m: 3}}) // {"a": "a","v": 2,"d": {"m":3}}

格式化写入到文件中的json

经常发现写入到文件中的json是挤在一起的,就想着有没有可能在写入的时候就格式化一下,发现JSON.stringify是提供了的,就是第三个参数,为数字的话,就是缩进的格数,为字符串的话,就是用这个字符串替代缩进,不过都有一个最大值的限制,数字不能大于10,字符串超过10的长度就取前10个字符。

fs.writeFileSync('./test.json', JSON.stringify({ a: 1, b: 2, c: 3 }, null, 4), 'utf-8'); //{ // "a": 1, // "b": 2, // "c": 3 //} fs.writeFileSync('./test.json', JSON.stringify({ a: 1, b: 2, c: 3 }, null, '----'), 'utf-8'); //{ //----"a": 1, //----"b": 2, //----"c": 3 //}

__EOF__

本文作者风行者夜色
本文链接https://www.cnblogs.com/aloneMing/p/17316102.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   风行者夜色  阅读(223)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示