首页 > 文章列表 > 如何用 JSON.parse(JSON.stringify()) 完整保存并恢复包含 ES5 和 ES6 函数的对象?

如何用 JSON.parse(JSON.stringify()) 完整保存并恢复包含 ES5 和 ES6 函数的对象?

102 2025-04-02

如何用 JSON.parse(JSON.stringify()) 完整保存并恢复包含 ES5 和 ES6 函数的对象?

在数据库中存储和恢复包含 ES5 和 ES6 函数的对象

许多应用场景需要将包含函数的对象序列化为字符串,存储到数据库中,并在需要时再反序列化回对象。 然而,标准的 JSON.stringify() 方法无法处理函数。本文介绍一种方法,能够完整保存和恢复包含 ES5 和 ES6 函数的对象。

解决方案:

可以使用自定义的序列化和反序列化函数来实现这一目标。这些函数会将函数转换为可序列化的字符串表示,并在反序列化时将其转换回函数。 这需要一个约定来标识和处理函数字符串。

示例代码:

以下示例展示了如何使用自定义函数 toJsonparseJson 来实现这一功能:

const toJson = (obj) => {
  const cache = new Map();
  return JSON.stringify(obj, (key, value) => {
    if (typeof value === 'function') {
      const funcString = value.toString();
      if (!cache.has(funcString)) {
        const id = cache.size + 1;
        cache.set(funcString, `__func_${id}__`);
      }
      return cache.get(funcString);
    }
    return value;
  });
};

const parseJson = (jsonString) => {
  const cache = new Map();
  return JSON.parse(jsonString, (key, value) => {
    if (typeof value === 'string' && value.startsWith('__func_')) {
      const id = parseInt(value.substring(7), 10);
      const funcString = cache.get(id);
      if (funcString) {
        return eval(`(${funcString})`); // 使用eval,请注意安全风险
      }
    }
    return value;
  });
};


const originalObject = {
  name: 'John Doe',
  age: 25,
  onGetName: function() {
    console.log(this.name);
  },
  onGetAge: () => {
    console.log(this.age);
  }
};

const jsonString = toJson(originalObject);
// ... 保存 jsonString 到数据库 ...

// ... 从数据库读取 jsonString ...
const retrievedJsonString = jsonString;

const retrievedObject = parseJson(retrievedJsonString);

retrievedObject.onGetName(); // 输出:John Doe
retrievedObject.onGetAge(); // 输出:25

说明:

  • toJson 函数使用 JSON.stringify 和一个自定义的 replacer 函数。 replacer 函数将函数转换为 __func_id__ 的形式,并将其存储在 cache 中。
  • parseJson 函数使用 JSON.parse 和一个自定义的 reviver 函数。 reviver 函数将 __func_id__ 转换为函数。 请注意,这里使用了 eval(),这在处理来自不受信任来源的数据时存在安全风险。 在生产环境中,应该考虑更安全的替代方案,例如使用一个更严格的函数解析器或避免直接使用 eval()

此方法提供了一种相对简单的解决方案,但务必谨慎处理 eval() 的安全风险。 对于大型项目或安全性要求较高的应用,建议探索更健壮和安全的序列化/反序列化库。

来源:1740353815