Stringify删除了具有Symbol键的JavaScript对象,也无法对其进行迭代

时间:2019-07-08 04:42:07

标签: javascript json

我正在使用Sequelize orm模块。这是orm的绝佳模块。但是在where选项上,有些东西连接了。

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

如您在上面的代码中所见,name属性具有对象Op.like作为键。我已经检查了Sequelize的Op的代码库,因此发现它是SymbolOp.like就是Symbol.for('like')

当然,使用orm本身没问题,但是我的问题是将option字符串化为json。 Json.stringify的结果如下(删除了符号键值):

{"where":{"name":{}}}

我必须保存where查询的所有历史记录,并在以后重用,但是还没有任何解决方案。 研究了许多字符串化库,例如circular-jsonjson-stringify-safe,但是仍然存在相同的问题。 也已阅读过此question,但对于value,使用Symbol而不是key的情况。 并尝试使用自定义替换器,但也无法对其进行迭代。

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

任何建议请帮助我。

1 个答案:

答案 0 :(得分:2)

如评论中所述,符号键专门从JSON.stringify中排除(或者相反,any keys在符号ToString期间抛出错误,称为符号do)。因此,它们出现在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"}}]}