如何实现深度遍历对象并转换所有键?兼顾性能及第三方库选型
深度对象键转换方案:第三方库与自研实现
一、可靠第三方库实现(基于Lodash)
你用Lodash实现的mapKeysDeep思路可行,只需补充类型定义和最大深度限制就能满足需求。Lodash的工具函数经过大量测试,性能与可靠性都有保障,优化后的代码如下:
import { isPlainObject, mapKeys, mapValues, map, isArray } from 'lodash'; type KeyTransformer = (key: string) => string; function transform( obj: Record<string, unknown> | unknown[], transformer: KeyTransformer, depth = 0, maxDepth = 10 ): Record<string, unknown> | unknown[] { // 超过最大深度直接返回原对象,避免无限递归 if (depth >= maxDepth) return obj; if (isPlainObject(obj)) { // 转换当前层级的键 const transformedObj = mapKeys(obj, (_, key) => transformer(key)); // 递归处理子属性,深度递增 return mapValues(transformedObj, value => transform(value, transformer, depth + 1, maxDepth)); } else if (isArray(obj)) { // 数组仅递归处理内部元素,索引无需转换 return map(obj, item => transform(item, transformer, depth + 1, maxDepth)); } else { // 非对象/数组类型直接返回原值 return obj; } } // 使用示例 const obj = { a: 1, b: [{ c: 1, d: [1, 2] }], e: { f: 'f', j: null }, h: [1, 2, 3] }; const capitalize: KeyTransformer = (key: string) => key.toUpperCase(); const transformedObj = transform(obj, capitalize);
核心说明
- 新增深度控制逻辑,默认最大深度10,可按需调整
- 完善TypeScript类型定义,支持数组输入输出
isPlainObject会自动过滤Date、RegExp等特殊对象,避免误转换其内部属性- Lodash工具函数经过性能优化,适合API调用这类高频场景
二、自研实现(无依赖,性能优先)
若不想引入第三方库,可自研递归+深度限制的实现,兼顾性能与可靠性:
type KeyTransformer = (key: string) => string; // 精准判断纯对象,过滤特殊内置对象 function isPlainObject(obj: unknown): obj is Record<string, unknown> { return typeof obj === 'object' && obj !== null && Object.prototype.toString.call(obj) === '[object Object]'; } function transform( obj: Record<string, unknown> | unknown[], transformer: KeyTransformer, depth = 0, maxDepth = 10 ): Record<string, unknown> | unknown[] { if (depth >= maxDepth) return obj; if (isPlainObject(obj)) { const result: Record<string, unknown> = {}; // 直接遍历键值对,减少中间对象创建,提升性能 for (const [key, value] of Object.entries(obj)) { result[transformer(key)] = transform(value, transformer, depth + 1, maxDepth); } return result; } else if (Array.isArray(obj)) { // 数组元素逐个递归处理,保持原顺序 return obj.map(item => transform(item, transformer, depth + 1, maxDepth)); } else { return obj; } } // 使用示例同前
性能优化点
- 直接遍历
Object.entries,避免第三方库的额外函数调用开销 - 直接构建结果对象,减少中间临时对象的创建
- 自定义
isPlainObject判断逻辑,比原生typeof更精准,避免误处理特殊对象
注意事项
null、undefined及原始类型(字符串、数字、布尔)直接返回原值- 数组索引无需转换,仅处理数组内部的对象元素
- 最大深度限制可通过
maxDepth参数灵活调整
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

