首页 > 解决方案 > 如何在 TypeScript 项目的 JSON 类中覆盖 JSON.stringify 方法,而不是在自定义调用中?

问题描述

我有 React Native 和 TypeScript 应用程序。每周都会从 Fabric 收到错误消息:JSON.stringify 无法序列化循环结构。没有错误的场景。而且我有很多使用 JSON.stringify 的第三方库。这意味着不可能在每个地方都放置自定义方法。因此我无法捕捉到这个错误。我的项目的根目录中有一个引导文件,我可以在其中覆盖所有类。我做了一个捕捉序列化循环结构的助手:

const getCircularReplacer = () => {
  const seen = new WeakSet();

  return (key: any, value: any) => {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) {
        return jsonStringify.circularReferenceReplacement;
      }
      seen.add(value);
    }

    return value;
  };
};

interface IJsonStringify {
  (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
  circularReferenceReplacement?: any;
}

export const jsonStringify: IJsonStringify = (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string => {
  return JSON.stringify(value, replacer || getCircularReplacer(), space);
};

当我尝试在我的引导文件中覆盖我的 JSON.stringify 时,如下所示:

JSON.stringify = (value: any) => {
  return jsonStringify(value);
};

我收到此错误:超出最大调用堆栈大小。请有人写下我做错了什么或建议我如何根据我的助手覆盖我的 JSON 类。

标签: javascriptjsontypescriptobjectstringify

解决方案


您的方法不仅会删除循环引用,还会删除任何看到的对象,请尝试使用:

function decycle(obj, stack = []) {
    if (!obj || typeof obj !== 'object')
        return obj;

    if (stack.includes(obj))
        return null;

    let s = stack.concat([obj]);

    return Array.isArray(obj)
        ? obj.map(x => decycle(x, s))
        : Object.fromEntries(
            Object.entries(obj)
                .map(([k, v]) => [k, decycle(v, s)]));
}

而你只是这样称呼它JSON.stringify(decycle(yourJson))

至于这个:

超出最大调用堆栈大小

您有一个递归函数,它在没有退出条件的情况下调用自身。


推荐阅读