0

0

使用 JSON.parse 与 reviver 函数深度修改嵌套对象属性

聖光之護

聖光之護

发布时间:2025-11-16 14:32:12

|

168人浏览过

|

来源于php中文网

原创

使用 JSON.parse 与 reviver 函数深度修改嵌套对象属性

本文探讨了如何在javascript中高效地处理具有未知深度嵌套的对象结构,并批量修改其内部属性。我们将重点介绍一种利用 `json.parse` 的 `reviver` 函数进行深度遍历和属性转换的简洁方法,该方法无需手动递归,即可实现对所有层级指定属性的统一设置,并分析其优缺点及适用场景。

深度嵌套对象属性修改的挑战

前端开发中,我们经常会遇到结构复杂、层级不定的数据对象,例如树形结构、菜单配置或文件系统表示等。这类对象通常包含 children 属性,其内部又可能嵌套相同结构的对象。当需要对所有层级中的某个特定属性(例如 ative 状态)进行统一修改时,传统的循环(如 forEach、map)或手动递归方法可能会变得复杂且冗长,尤其是在对象深度未知的情况下。

例如,考虑以下对象结构,其中 ative 属性可能在任何层级出现,并且 children 数组的深度是可变的:

const obj = {
  name: 'obj1',
  ative: true,
  children: [
    {
      name: 'obj2',
      ative: true,
      children: [
        {
          name: 'Obj23',
          ative: true,
          children: [] // 可能是空数组,表示没有子节点
        }
      ]
    },
    {
      name: 'obj3',
      children: [ // 注意:此对象本身没有 ative 属性
        {
          name: 'Obj32',
          ative: true,
          children: []
        }
      ]
    }
  ]
};

我们的目标是遍历 obj 及其所有子孙节点,将所有存在的 ative 属性设置为 false。

利用 JSON.parse 与 reviver 函数进行深度转换

JavaScript 的 JSON 对象提供了一个非常强大的机制来实现对深层对象的转换:JSON.parse() 方法的第二个参数——reviver 函数。reviver 函数允许我们在解析JSON字符串时,对每个键值对进行检查和转换。

工作原理

  1. JSON.stringify(obj): 首先,我们将原始对象 obj 转换为其JSON字符串表示。这一步实际上创建了一个原始对象的深拷贝,因为JSON字符串不包含引用。

  2. JSON.parse(jsonString, reviver): 接着,我们使用 JSON.parse 将JSON字符串解析回JavaScript对象。在解析过程中,reviver 函数会为JSON字符串中遇到的每一个键值对(包括嵌套对象和数组中的元素)被调用。

    Amazon ML
    Amazon ML

    Amazon AMZ机器学习平台

    下载

    reviver 函数的签名是 function(key, value),它接收当前处理的键 (key) 和值 (value) 作为参数。该函数的返回值将替换原始值:

    • 如果 reviver 返回 value,则该键值对保持不变。
    • 如果 reviver 返回一个不同的值,则该键值对的值将被替换为新的返回值。
    • 如果 reviver 返回 undefined,则该键值对将从结果对象中删除。

示例代码

针对上述问题,我们可以这样使用 JSON.parse 和 reviver 来将所有 ative 属性设置为 false:

const obj = {
    name: 'obj1',
    ative: true,
    children: [{
        name: 'obj2',
        ative: true,
        children: [{
            name: 'Obj23',
            ative: true,
            children: []
        }]
    },
    {
        name: 'obj3',
        children: [{
            name: 'Obj32',
            ative: true,
            children: []
        }]
    }]
};

const result = JSON.parse(JSON.stringify(obj), (key, value) => {
    // 如果当前键是 'ative',则将其值设置为 false
    if (key === 'ative') {
        return false;
    }
    // 否则,返回原始值,保持不变
    return value;
});

console.log(result);

运行上述代码,result 对象将是 obj 的一个深拷贝,但其中所有名为 ative 的属性都已被设置为 false:

/* console.log(result) 的输出 */
{
  name: 'obj1',
  ative: false, // 已被修改
  children: [
    {
      name: 'obj2',
      ative: false, // 已被修改
      children: [
        {
          name: 'Obj23',
          ative: false, // 已被修改
          children: []
        }
      ]
    },
    {
      name: 'obj3',
      children: [
        {
          name: 'Obj32',
          ative: false, // 已被修改
          children: []
        }
      ]
    }
  ]
}

代码解析

  • JSON.stringify(obj): 将原始 obj 转换为JSON字符串。
  • (key, value) => key === 'ative' ? false : value: 这是一个箭头函数,作为 reviver 传递给 JSON.parse。
    • 它会检查每个键。如果 key 等于字符串 'ative',那么它就返回 false。
    • 对于所有其他键,它返回原始的 value,不做任何修改。
    • 这种机制确保了只有目标属性被修改,而其他属性和结构保持不变。

注意事项与局限性

虽然 JSON.parse 结合 reviver 提供了一种简洁的解决方案,但它并非适用于所有场景。在使用时需要注意以下几点:

  1. 数据类型限制:JSON.stringify 无法正确处理所有JavaScript数据类型。它会:
    • 忽略函数(function)、undefined 和 Symbol 值。
    • 将 Date 对象转换为ISO格式的字符串。
    • 将 RegExp 和 Error 对象转换为 {}。
    • 如果对象包含循环引用,JSON.stringify 将抛出错误。 因此,如果你的对象包含这些特殊类型或循环引用,此方法可能不适用。
  2. 性能开销:对于非常庞大的对象,先将其转换为字符串再解析回对象可能会比直接的递归遍历消耗更多的CPU和内存资源。在对性能要求极高的场景下,传统的递归方法可能更为高效。
  3. 深拷贝特性:此方法总是会生成一个全新的深拷贝对象。这意味着原始对象不会被修改。如果你的需求是原地修改原始对象,那么你需要采用其他方法(如递归遍历)。
  4. 键的匹配:reviver 函数只根据键名进行匹配。如果你的需求是根据键值、数据类型或更复杂的逻辑进行判断和修改,reviver 仍然能够胜任,只需在回调函数中添加相应的判断逻辑即可。

总结

利用 JSON.parse 与 reviver 函数是处理深度嵌套对象并批量修改特定属性的一种优雅且高效的方法。它通过将对象序列化再反序列化的过程,巧妙地利用了 reviver 的回调机制,避免了手动编写复杂的递归逻辑。然而,开发者在使用此方法时,必须充分了解其对数据类型的限制以及性能影响,并根据具体需求权衡选择。对于结构相对简单、不含特殊数据类型且需要深拷贝并转换的场景,这无疑是一个极佳的解决方案。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

552

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

730

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

475

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

990

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

656

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

551

2023.09.20

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

8

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.1万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号