本文介绍两种主流方式:一是将原始键值对对象转换为“每个子对象自带 name 字段”的新对象;二是转换为标准数组格式,便于后续遍历或渲染。代码简洁、兼容性好,适用于 API 响应结构标准化场景。
本文介绍两种主流方式:一是将原始键值对对象转换为“每个子对象自带 `name` 字段”的新对象;二是转换为标准数组格式,便于后续遍历或渲染。代码简洁、兼容性好,适用于 api 响应结构标准化场景。
在实际前端开发中,我们常遇到 API 返回的是以服务名(如 "akash"、"aptos")为键的扁平化对象,但业务逻辑或 UI 组件(如列表、下拉框、卡片组件)更期望每个条目是结构统一的独立对象——尤其是需要显式标识名称时。此时,为每个子对象注入 name 字段(值即其父级键名),是关键的数据预处理步骤。
✅ 方案一:保持对象结构,仅增强子对象属性
使用 for...in 遍历原始对象的可枚举键,并通过展开运算符(...)安全合并原有属性与新增的 name 字段:
const apiResponse = {
akash: { url: "127.0.0.1", count: 12 },
aptos: { url: "127.0.0.2", count: 54 }
};
const enhancedObject = {};
for (const key in apiResponse) {
if (apiResponse.hasOwnProperty(key)) { // 推荐:确保只处理自身属性,避免原型污染
enhancedObject[key] = { ...apiResponse[key], name: key };
}
}
console.log(enhancedObject);
// 输出:
// {
// akash: { name: "akash", url: "127.0.0.1", count: 12 },
// aptos: { name: "aptos", url: "127.0.0.2", count: 54 }
// }⚠️ 注意:务必添加 hasOwnProperty 检查,防止继承属性被意外处理;若确定数据纯净(如 JSON 解析结果),可省略,但属于最佳实践。
✅ 方案二:转为标准数组(推荐用于列表渲染)
当需传递给 map() 渲染、排序、搜索或与其他数组合并时,数组格式更具通用性:
const apiResponse = {
akash: { url: "127.0.0.1", count: 12 },
aptos: { url: "127.0.0.2", count: 54 }
};
const itemsArray = Object.entries(apiResponse).map(([key, value]) => ({
name: key,
...value
}));
console.log(itemsArray);
// 输出:
// [
// { name: "akash", url: "127.0.0.1", count: 12 },
// { name: "aptos", url: "127.0.0.2", count: 54 }
// ]Object.entries() 返回 [key, value] 数组,配合 map() 更函数式、更简洁,且天然规避原型链问题,是现代 JS 的首选写法。
? 总结与建议
- 若需保留原始键名语义(如快速通过 obj.aptos 访问),选方案一;
- 若面向列表展示、状态管理(如 Redux/Vuex)、或需与其他数组交互,方案二(数组)更灵活、更符合前端工程惯例;
- 两种方式均不修改原对象(纯函数式),保障数据不可变性;
- 如需深度克隆(子对象含嵌套引用),请替换 ...value 为结构化克隆(如 structuredClone(value) 或第三方库)。
无论哪种形式,核心逻辑始终一致:利用对象键名作为有意义的元信息,注入到对应子对象中,完成从“结构索引”到“语义实体”的升级。










