You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义JSON循环结构处理函数导致输出截断的原因解析

JSON.stringify循环引用处理函数导致输出截断的原因及修复

问题重现

为解决JSON转换循环结构报错,编写了以下处理函数:

circular = () => { //fix circular stuff for json.stringify
  seen = new WeakSet();
  return (key, value) => {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    return value;
  };
};

在以下场景中出现输出"截断"问题:

var gameon = 1;
var fighter1 = {"userid":"97","username":"john","items":{},"ailments":{}};
var fighter2 = {"userid":"91","username":"james","items":{},"ailments":{}};
var resume = 30;

all = {"gameon":gameon,"fighter1":fighter1,"fighter2":fighter2,"resume":30,"inturn":fighter1,"outturn":fighter2};
    
console.log(JSON.stringify(all,circular()));

执行后输出仅到resume字段就结束,后续的inturn和outturn字段丢失:

{"gameon":1,"fighter1":{"userid":"97","username":"john","items":{},"ailments":{}},"fighter2":{"userid":"91","username":"james","items":{},"ailments":{}},"resume":30}

(注:你提供的输出末尾多了一个多余引号,应为输入失误)

原因分析

  1. 重复引用返回undefined导致键值对被忽略:
    当JSON.stringify遍历到inturn: fighter1时,fighter1对象已经在处理fighter1字段时被加入了seen WeakSet,此时处理函数返回undefined。而JSON.stringify的规则是:如果replacer函数返回undefined,对应的键值对会被直接跳过,不会出现在最终的JSON字符串中。同理outturn: fighter2也会被跳过,看起来像是输出被"截断"。

  2. 全局变量seen的潜在污染:
    函数中的seen没有用let/const声明,属于隐式全局变量。如果多次调用circular(),会导致seen被重复覆盖,可能引发其他场景下的异常。

修复方案

修改处理函数,针对重复引用返回可序列化的标识,同时将seen改为闭包局部变量:

const circular = () => { 
  const seen = new WeakSet(); // 改为局部变量,避免全局污染
  return (key, value) => {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) {
        // 返回自定义标识,而非undefined,保留键值对
        return `[Circular Reference: ${value.userid || key}]`;
        // 也可以直接返回对象的唯一标识,比如value.userid
        // return value.userid;
      }
      seen.add(value);
    }
    return value;
  };
};

修改后,再执行原测试代码,输出会保留inturn和outturn字段,显示为自定义的循环引用标识,不会出现"截断":

{"gameon":1,"fighter1":{"userid":"97","username":"john","items":{},"ailments":{}},"fighter2":{"userid":"91","username":"james","items":{},"ailments":{}},"resume":30,"inturn":"[Circular Reference: 97]","outturn":"[Circular Reference: 91]"}

内容的提问来源于stack exchange,提问作者Cain Nuke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:05:52