如何在JavaScript中按路径修改嵌套对象的键并保留顺序?
修改嵌套对象的键并保留原有顺序
要实现已知嵌套路径的键重命名且保留键的原有顺序,不用递归遍历整个对象结构,可以通过原生JS结合路径拆分+键值对数组操作来实现,也可以借助工具库简化流程,具体方案如下:
原生JS实现方案
核心思路:拆分目标路径找到父对象,将父对象转换为键值对数组(保留原有顺序),替换目标键名后再转回对象,最后覆盖父对象的内容。
代码示例
function renameNestedKey(targetObj, keyPath, newKeyName) { // 拆分路径为层级数组 const pathSegments = keyPath.split('.'); // 提取父对象路径和原键名 const parentSegments = pathSegments.slice(0, -1); const oldKey = pathSegments.at(-1); // 遍历路径定位父对象 let parentObj = targetObj; for (const segment of parentSegments) { parentObj = parentObj[segment]; // 路径不存在时直接终止 if (!parentObj) return; } // 原键不存在时终止 if (!(oldKey in parentObj)) return; // 替换键名并保留顺序 const updatedEntries = Object.entries(parentObj).map(([key, value]) => key === oldKey ? [newKeyName, value] : [key, value] ); // 清空父对象并重新赋值(保持原引用关系) Object.keys(parentObj).forEach(key => delete parentObj[key]); Object.assign(parentObj, Object.fromEntries(updatedEntries)); } // 使用示例 const sampleObj = { "name": { "firstname": "Boba", "lastName": "Fett" } }; renameNestedKey(sampleObj, 'name.firstname', 'FullName'); console.log(sampleObj); // 输出:{ name: { FullName: 'Boba', lastName: 'Fett' } }
原理说明
- ES6及以后,对象的字符串/Symbol键会按插入顺序保存,
Object.entries()会遵循该顺序返回键值对数组。 - 通过
Object.fromEntries()将修改后的数组转回对象,能完整保留原有的键顺序。 - 这里的路径遍历是线性循环,并非递归遍历整个对象结构,符合需求。
工具库简化方案
如果不想手动实现路径遍历,可以用object-path库简化父对象的获取,核心顺序保留逻辑仍依赖原生操作:
const objectPath = require('object-path'); function renameNestedKeyWithLib(targetObj, keyPath, newKeyName) { const pathSegments = keyPath.split('.'); const oldKey = pathSegments.at(-1); // 用库快速定位父对象 const parentObj = objectPath.get(targetObj, pathSegments.slice(0, -1)); if (!parentObj || !(oldKey in parentObj)) return; // 同原生方案的键替换逻辑 const updatedEntries = Object.entries(parentObj).map(([key, value]) => key === oldKey ? [newKeyName, value] : [key, value] ); Object.keys(parentObj).forEach(key => delete parentObj[key]); Object.assign(parentObj, Object.fromEntries(updatedEntries)); }
内容的提问来源于stack exchange,提问作者Gevin Hasmitha
相关产品推荐
相关产品推荐

