【问题标题】:use JSON.parse reviver to force value of undefined in resulting object rather than cause property to be omitted使用 JSON.parse reviver 在结果对象中强制 undefined 的值,而不是导致属性被省略
【发布时间】:2018-08-11 18:11:52
【问题描述】:

JSON.parse 将序列化的 Json 作为参数并反序列化它。第二个(可选)参数是一个 reviver 函数,它采用键和值并返回反序列化对象中的替换值。记录在案的行为是,如果 reviver 返回未定义或不返回任何内容,则相关属性将从生成的反序列化对象中省略。

我有一种情况,我希望相关属性包含在结果反序列化对象中,值为 undefined。

因此,例如,以下是当前正确的:

JSON.parse(JSON.stringify({a: 1, b:2}), (k, v) => v===2 ? undefined : v);
// result of this is {a:1}, as is documented/expected.

但如果我真的想要结果是什么

{a:1, b:undefined}

有没有办法写reviver来做到这一点?

我特别不想在反序列化后再次遍历对象,所以请不要建议将其作为解决方案。另外我特别不希望将 b 设置为空。我真的希望它以未定义值的属性的形式出现。

这可能根本不可能,但我希望有人有一个好主意!

第一次编辑:

第一个建议是很好的尝试,但我还需要它在深层结构中工作,所以如下:

JSON.parse(JSON.stringify({
    a: 1,
    b:{
        c: 1,
        d: 2,
        e: [
            1, 
            2,
            {
                f: 1,
                g: 2
            },
            4
        ]
    }
}), (k, v) => v===2 ? undefined : v);

应该在我的理想世界中产生:

{
    a: 1,
    b:{
        c: 1,
        d: undefined,
        e: [
            1, 
            undefined,
            {
                f: 1,
                g: undefined
            },
            4
        ]
    }
}

【问题讨论】:

  • 改用null
  • 谢谢,但我已经在问题中明确表示不能工作。
  • 啊,我读多了。通常null 或只是一个未定义的属性(访问时以undefined 结尾)就足够了。

标签: javascript json deserialization json-deserialization


【解决方案1】:

我怀疑这可以通过简单的 reviver 和 JSON.parse 来完成。

我不知道这是否会满足您的限制,而且它很丑陋,但这里有一个方法:将JSON.parse 包装在存储来自您的 reviver 的 undefined 键的东西中,并在最后添加它们。这不需要再次迭代您明确拒绝的对象,但它确实迭代了 undefined 键的列表:

const myParse = (obj, reviver) => {
  if (typeof reviver !== 'function') {
    return JSON.parse(obj)
  }
  const undefs = []
  const rev = (k, v) => {
    const val = reviver(k, v)
    if (typeof val === 'undefined') {
      undefs.push(k)
    }
    return val;
  }
  const ret = JSON.parse(obj, rev)
  undefs.forEach(k => ret[k] = undefined)
  return ret
}

const result = myParse(
  JSON.stringify({a: 1, b:2}), 
  (k, v) => v===2 ? undefined : v
)

console.log(result)

【讨论】:

  • 漂亮又丑陋的尝试。现在的问题是: myParse( JSON.stringify({a: 1, b:{c: 1, d:2}}), (k, v) => v===2 ? undefined : v ) 这会产生{a: 1, b: {c: 1}, d: undefined - 如果我们想这样做,我们需要以某种方式获取 reviver 中键的完整上下文。
  • 哦,当然...我不经常与 revivers 一起工作,但是考虑到他们的 API,如果不重写 JSON.parse 所做的很多事情,我认为你很不走运。有许多实现浮动,您可以修改一个以不同方式处理undefined。不过,抱歉,这听起来不好玩。
猜你喜欢
  • 2017-03-05
  • 1970-01-01
  • 2019-03-28
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多