如何通过JSON.stringify的replacer函数正确匹配指定namespace路径?
解决JSON路径匹配错误的思路
问题根源
当前逻辑仅通过「键名匹配就递增索引」的方式追踪路径,没有维护严格的层级匹配状态——当深层嵌套中出现与namespace节点同名的键时,会错误推进匹配索引,导致非目标路径被误识别。
具体解决思路
- 维护层级匹配状态栈:用栈记录每一层对象的匹配深度,进入对象时压入当前层级状态,离开时弹出,确保递归处理时的路径上下文正确。
- 初始栈值为
[0],代表当前匹配到namespace的第0层(未开始匹配)。 - 处理对象的键时:若当前键等于
namespace[当前栈顶深度],则新深度为栈顶深度+1;若已匹配部分路径但当前键不匹配,直接重置深度为0,避免深层同名键干扰。
- 初始栈值为
- 严格校验完整路径:仅当匹配深度等于namespace的长度时,才判定到达目标路径。比如
namespace = ['styles','typography','fontSize'],只有当深度达到3时,才触发标记操作。 - 修正replacer中的对象修改逻辑:在replacer中返回新对象(而非修改原对象),确保目标值所在对象添加
0和Z键时,不会影响其他路径的处理。
修正后的核心逻辑示例
const namespace = ['styles', 'typography', 'fontSize']; const matchStack = [0]; function replacer(key, value) { // 进入对象时更新匹配栈 if (typeof value === 'object' && value !== null) { const currentDepth = matchStack.at(-1); let newDepth = currentDepth; if (key === namespace[currentDepth]) { newDepth += 1; } else if (currentDepth > 0) { // 偏离目标路径,重置匹配深度 newDepth = 0; } matchStack.push(newDepth); } // 匹配到完整目标路径时,修改对象 const currentDepth = matchStack.at(-1); if (currentDepth === namespace.length && key === namespace.at(-1)) { return { ...this, 0: value, Z: value }; } // 离开对象时弹出栈顶状态 if (typeof value === 'object' && value !== null) { matchStack.pop(); } return value; }
内容的提问来源于stack exchange,提问作者Romain Guillaume
相关产品推荐
相关产品推荐

