使用JSON.parse reviver在结果对象中强制undefined的值而不是导致属性被省略

问题描述 投票:1回答:1

JSON.parse将序列化的Json作为参数并反序列化。第二个(可选)参数是一个reviver函数,它接受一个键和值,并在反序列化的对象中返回替换值。记录的行为是reviver,如果它返回undefined或什么都没有,那么将从生成的反序列化对象中省略所讨论的属性。

我有一种情况,我希望有问题的属性包含在生成的反序列化对象中,其值为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被设置为null。我真的希望它作为属性存在,其值为undefined。

这可能根本不可能,但我希望有人有一个漂亮的想法!

第一次编辑:

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

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
        ]
    }
}
javascript json deserialization json-deserialization
1个回答
0
投票

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

我不知道这是否会满足你的约束,而且它像罪一样丑陋,但这是一种方法:将JSON.parse包装在存储来自你的复活者的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)
© www.soinside.com 2019 - 2024. All rights reserved.