导读:本期聚焦于小伙伴创作的《如何将嵌套对象中各层级的键值对扁平合并为单个对象(无嵌套结构)》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何将嵌套对象中各层级的键值对扁平合并为单个对象(无嵌套结构)》有用,将其分享出去将是对创作者最好的鼓励。

在前端开发、数据处理等场景中,经常会遇到多层嵌套的对象结构,比如接口返回的用户信息、配置项数据等,这些嵌套结构往往不方便直接进行遍历、查找或存储操作,此时就需要将嵌套对象中各层级的键值对扁平合并为单个无嵌套结构的对象,让所有属性都直接挂载在顶层对象上。

如何将嵌套对象中各层级的键值对扁平合并为单个对象(无嵌套结构)

基础场景:仅处理对象嵌套,无数组混合

如果嵌套对象中只有对象类型的嵌套,没有数组、Map等其他复杂类型,我们可以通过递归遍历的方式实现扁平化。核心逻辑是遍历当前对象的所有属性,如果属性值是对象且不是null,就递归处理该属性值,将得到的扁平键值对的键拼接当前属性名作为新的键,否则直接将当前键值对放入结果对象中。

以下是具体的实现代码:

// 基础对象扁平化函数,仅处理对象嵌套场景
function flattenObject(obj, prefix = '', result = {}) {
  // 遍历对象的所有自有属性
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 拼接当前键的前缀,形成最终的键名
      const newKey = prefix ? `${prefix}_${key}` : key;
      // 判断当前值是否为对象且不是null,是则递归处理
      if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
        flattenObject(obj[key], newKey, result);
      } else {
        // 非对象值直接存入结果
        result[newKey] = obj[key];
      }
    }
  }
  return result;
}

// 测试示例
const nestedObj = {
  name: '张三',
  age: 25,
  address: {
    province: '广东',
    city: '深圳',
    detail: {
      street: '科技路',
      number: 100
    }
  }
};

const flatObj = flattenObject(nestedObj);
console.log(flatObj);
// 输出结果:
// {
//   name: '张三',
//   age: 25,
//   address_province: '广东',
//   address_city: '深圳',
//   address_detail_street: '科技路',
//   address_detail_number: 100
// }

复杂场景:支持数组、多层混合嵌套

实际开发中嵌套对象可能会混合数组结构,比如某个属性的值是对象数组,这时候需要在基础逻辑上增加对数组的处理,遍历数组的每一项,给每一项拼接索引作为键的一部分,再递归处理数组项的内容。

以下是支持数组混合嵌套的扁平化实现:

// 支持数组混合的通用对象扁平化函数
function flattenComplexObject(obj, prefix = '', result = {}) {
  // 处理数组类型
  if (Array.isArray(obj)) {
    obj.forEach((item, index) => {
      const newKey = prefix ? `${prefix}_${index}` : `${index}`;
      // 数组项如果是对象或数组,继续递归
      if (typeof item === 'object' && item !== null) {
        flattenComplexObject(item, newKey, result);
      } else {
        result[newKey] = item;
      }
    });
  } else if (typeof obj === 'object' && obj !== null) {
    // 处理对象类型
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        const newKey = prefix ? `${prefix}_${key}` : key;
        if (typeof obj[key] === 'object' && obj[key] !== null) {
          flattenComplexObject(obj[key], newKey, result);
        } else {
          result[newKey] = obj[key];
        }
      }
    }
  } else {
    // 基本类型直接赋值
    result[prefix] = obj;
  }
  return result;
}

// 测试示例
const complexNestedObj = {
  id: 1,
  list: [
    { title: '第一项', value: 10 },
    { title: '第二项', value: 20 }
  ],
  info: {
    owner: '李四',
    tags: ['前端', 'JavaScript']
  }
};

const complexFlatObj = flattenComplexObject(complexNestedObj);
console.log(complexFlatObj);
// 输出结果:
// {
//   id: 1,
//   list_0_title: '第一项',
//   list_0_value: 10,
//   list_1_title: '第二项',
//   list_1_value: 20,
//   info_owner: '李四',
//   info_tags_0: '前端',
//   info_tags_1: 'JavaScript'
// }

实现注意事项

  • 递归处理时需要注意判断值为null的情况,因为typeof null返回的是object,要避免把null当成对象递归处理。
  • 键名拼接的规则可以根据实际需求调整,比如部分场景下可能需要用点号而不是下划线作为连接符,只需要修改拼接字符串的逻辑即可。
  • 如果嵌套层级非常深,递归可能会导致栈溢出,此时可以考虑改用迭代的方式实现,用栈或队列存储待处理的对象,避免递归过深的问题。

迭代实现方式(避免深递归栈溢出)

如果处理的嵌套对象层级非常深,递归实现可能会出现栈溢出的问题,这时候可以用迭代的方式,通过栈来存储待处理的对象和当前的前缀信息,逐步处理所有层级的属性。

// 迭代方式实现对象扁平化,避免深递归栈溢出
function flattenObjectIterative(obj) {
  const result = {};
  // 栈中存储待处理的对象、当前前缀
  const stack = [{ data: obj, prefix: '' }];
  
  while (stack.length > 0) {
    const { data, prefix } = stack.pop();
    // 处理数组
    if (Array.isArray(data)) {
      data.forEach((item, index) => {
        const newKey = prefix ? `${prefix}_${index}` : `${index}`;
        if (typeof item === 'object' && item !== null) {
          stack.push({ data: item, prefix: newKey });
        } else {
          result[newKey] = item;
        }
      });
    } else if (typeof data === 'object' && data !== null) {
      // 处理对象
      for (let key in data) {
        if (data.hasOwnProperty(key)) {
          const newKey = prefix ? `${prefix}_${key}` : key;
          if (typeof data[key] === 'object' && data[key] !== null) {
            stack.push({ data: data[key], prefix: newKey });
          } else {
            result[newKey] = data[key];
          }
        }
      }
    } else {
      // 基本类型
      result[prefix] = data;
    }
  }
  return result;
}

// 测试示例
const deepNestedObj = {
  a: {
    b: {
      c: {
        d: {
          e: '深层值'
        }
      }
    }
  }
};

const iterativeFlatObj = flattenObjectIterative(deepNestedObj);
console.log(iterativeFlatObj); // { a_b_c_d_e: '深层值' }

对象扁平化嵌套对象处理JavaScript键值对合并修改时间:2026-06-28 18:54:35

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。