带有 Symbol 键的 JavaScript 对象被 Stringify 删除,也无法迭代

ren*_*846 3 javascript json

我正在使用 Sequelize orm 模块。这是一个很棒的 orm 模块。但在 where 选项上有一些问题。

const option = { where: { name: { [Op.like]: `%${name}%` } } }
const result = await model.findOne(option)
Run Code Online (Sandbox Code Playgroud)

正如您在上面的代码中看到的,该name属性以对象Op.like作为键。我检查了 Sequelize 的代码库Op,发现它是Symbol. 这Op.like只是Symbol.for('like')

当然,使用orm本身没有问题,但我的问题在于将optionas json字符串化。结果Json.stringify如下(Symbol 键值被删除):

{"where":{"name":{}}}
Run Code Online (Sandbox Code Playgroud)

我必须保存所有where查询历史记录并稍后重用,但没有任何解决方案。研究了许多 stringify 库,例如circular-jsonjson-stringify-safe,但仍然存在同样的问题。也读过这个问题,但这是使用符号的情况value,而不是key。并尝试使用自定义替换器,但也无法迭代。

JSON.stringify(option, (key, value) => {
  if(typeof key === 'symbol') {
    console.log('symbol key: ', key) // nothing detected here
  }
  return value
})
Run Code Online (Sandbox Code Playgroud)

请帮助我任何建议。

Ama*_*dan 5

正如评论中提到的,符号键被明确排除在外JSON.stringify(或者更确切地说,任何在其期间抛出错误的ToString,就像符号一样)。因此,它们出现的唯一方法JSON.stringify就是用字符串键替换它们。

function desymbolize(o) {
  if (Array.isArray(o)) {
    return o.map(desymbolize);
  } else if (typeof o != "object") {
    return o;
  } else {
    let d = Object.assign(Object.create(Object.getPrototypeOf(o)), o);
    Object.getOwnPropertySymbols(o).forEach(k => {
      d[`<${Symbol.keyFor(k)}>`] = o[k];
      delete d[k];
    });
    Object.keys(d).forEach(k => d[k] = desymbolize(d[k]));
    return d;
  }
}

const Op = { like: Symbol.for('like') };
const option = { where: [{ name: { [Op.like]: `Amadan` } }] }
const desymOption = desymbolize(option);
console.log(JSON.stringify(desymOption)); // {"where":[{"name":{"<like>":"Amadan"}}]}
Run Code Online (Sandbox Code Playgroud)