You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JSON.parse的reviver函数中展开对象值并移除原键

问题描述

我希望能够在JSON.parse的reviver函数中展开指定条目的值,同时删除对应的原始键,但直接返回展开后的值无法实现该效果。

示例代码

JavaScript逻辑代码:

const json = {a: 'foo', b: {c: 1, d: '2'}}
const stringify = JSON.stringify(json)

const parsed = JSON.parse(stringify, function(k, v) {
  if(k === 'b') {
    return {...v}
  } else {
    return v
  }
})

document.getElementById("app").innerHTML = `<pre>${JSON.stringify(parsed, null, 2)}</pre>`;

配套页面HTML代码:

<div id="app"></div>

期望输出

{
  "a": "foo",
  "c": 1,
  "d": "2"
}

原因说明

JSON.parse的reviver函数本身不支持将返回值展开合并到父级对象,reviver的返回值只会直接替换当前遍历到的键对应的值,不会自动做属性合并。原写法中返回{...v}本质和直接返回v没有区别,最终b键依然会挂载在父对象上,无法达到删除原键、展开属性的效果。

实现方法

利用reviver深度优先遍历的特性,在遍历到父级普通对象时,检测是否存在需要展开的子键,手动完成属性合并后删除原始键即可:

const parsed = JSON.parse(stringify, function(k, v) {
  // 仅处理普通对象类型的值,跳过数组、null等特殊情况
  if (typeof v === 'object' && v !== null && !Array.isArray(v)) {
    // 检测到存在需要展开的键b
    if (Object.prototype.hasOwnProperty.call(v, 'b')) {
      // 将b下的所有属性合并到当前对象
      Object.assign(v, v.b);
      // 删除原始的b键
      delete v.b;
    }
  }
  return v
})

运行上述代码得到的结果和期望输出完全一致。如果有多个需要展开的键,只需要在判断逻辑中追加对应的处理分支即可,深度优先的遍历顺序会保证内层待展开的键先完成处理,不会出现属性丢失问题。


内容的提问来源于stack exchange,提问作者baba-dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:00:49