deepConvert
deepConvert方法可以深度遍历一个对象,根据你设计的规则进行一些数据处理。 与独立的递归处理 treeForEach 或者 treeMap 不同的是,这个方法通常用于一个规模更大,且更复杂,更频繁的处理策略。 比如我曾将它用于构造一个超json翻译器,用于存储低代码配置。
语法
javascript
deepConvert(data, scope, convertFunc, isTerminator)参数
data any
需要深度遍历处理的数据,通常是大型对象或数组,也可以是任意类型的值。
scope object
一个数据暂存区域,用于在递归过程中保存数据。 我一般把这里的数据分为两种,一种类似 key 和 parent,每次递归都会变化。 另一种则只会增加,可以保留整个对象的特征。
deepConvert 在遍历时会自动向 scope 注入以下属性:
scope.key— 当前正在处理的键名scope.parent— 当前层级的容器对象(对象或数组)
convertFunc function
转换函数,当终止条件满足时被调用,接收当前值和 scope 作为参数,返回转换后的结果。
参数:
data— 当前正在处理的值scope— 当前作用域对象
返回值:转换后的值,将作为该位置的新值。
isTerminator function
终止符判断函数,用于决定是否停止对当前分支的深度遍历。接收当前值和 scope 作为参数。
参数:
data— 当前正在处理的值scope— 当前作用域对象
返回值:
- 返回
true:终止当前分支遍历,调用convertFunc转换后返回 - 返回
'deep':调用convertFunc转换后,对转换结果继续深度遍历(支持链式转换) - 返回其他假值:继续深度遍历当前值
返回值
any返回处理后的数据,结构与输入数据对应。如果是对象/数组则返回新的容器,基本类型值直接返回。
描述
deepConvert 是一个通用的深度遍历转换函数,它的工作流程如下:
- 终止符检查:首先调用
isTerminator(data, scope),如果返回'deep',则先调用convertFunc转换数据,再对转换结果继续递归处理;如果返回true,则调用convertFunc转换数据并直接返回结果。 - 容器遍历:如果数据是对象或数组,创建对应类型的新容器,然后遍历每个属性。遍历时自动更新
scope.key和scope.parent。 - 数组处理:对于数组容器,
convertFunc返回undefined的项会被跳过(不加入新数组)。 - 基本类型:如果数据不是对象或数组,且未触发终止条件,直接返回原值。
重要特性:
- 支持链式转换:当
isTerminator返回'deep'时,转换后的结果会继续被深度遍历 - 数组中返回
undefined的项会被自动过滤 scope对象在遍历过程中会被复用和修改,实现数据在递归层级间的传递
注意事项
scope对象在递归过程中会被修改(scope.key和scope.parent),不要在convertFunc或isTerminator中依赖 scope 的快照isTerminator必须正确设置终止条件,否则可能导致无限递归- 该函数不使用
treeSafe,传入的data如果是单个对象会正常处理(作为对象容器遍历) convertFunc对于数组项返回undefined时,该项会被跳过
示例
基础用法 — 字符串值转换
使用 'deep' 实现链式转换
过滤数组项
浏览器兼容
此功能在所有现代浏览器和 Node.js 环境中均受支持,不依赖任何浏览器特定 API。
性能考虑
- 时间复杂度:O(n) — 其中 n 是数据中所有节点(包括嵌套节点)的总数,每个节点访问一次
- 空间复杂度:O(d) — 其中 d 是数据的最大嵌套深度,用于递归调用栈
- 对于超大型对象,注意递归深度可能导致的栈溢出问题
scope对象在递归中复用,不会产生额外的内存开销
相关函数
- createMyTrans — 基于 deepConvert 构建的翻译器,预设了丰富的转换规则
- dlsjsTrans — dlsjs 预设翻译器实例
- treeForEach — 简单的树形遍历,不涉及转换
- treeMap — 树形映射,返回新树
- RW — 高级读写代理,与 deepConvert 配合可实现复杂的数据访问