You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用recursive-iterator迭代对象时报错:无法解构未定义的valueOnDeepClone

问题根因

报错的核心原因是两个迭代器遍历步调不一致:旧对象中的modifiedProperties是空数组,迭代器不会进入数组内部遍历;新对象中的modifiedProperties是带元素的非空数组,迭代器会额外遍历数组内的每一项,导致新对象迭代器比旧对象多走若干步,旧对象先遍历完成后next()返回的value为undefined,解构属性时就会抛出类型错误。

解决方案

方案1:配置迭代器过滤规则

RecursiveIterator第二个参数支持传入自定义过滤函数,返回false的节点不会进入递归遍历,我们可以直接跳过modifiedProperties属性,保证两个迭代器步调完全一致:

// 自定义过滤器:跳过modifiedProperties属性的递归遍历
const traverseFilter = (node: any, key: string | number) => {
  return key !== 'modifiedProperties';
}

const iteratorOnDeepClone = new RecursiveIterator(old, traverseFilter, true);
const iteratorOnModifiedObject = new RecursiveIterator(n, traverseFilter, true);

如果你的遍历逻辑不需要处理数组类型,也可以在过滤规则中增加Array.isArray(node) && return false的判断,进一步避免类似的步调不一致问题。

方案2:补充迭代完成状态判断

调整循环逻辑,优先判断两个迭代器的done标记,只要任意一个迭代完成就直接退出循环,避免访问undefined的返回值:

while (true) {
  const { value: valueOnModifiedObject, done: doneOnModifiedObject } = iteratorOnModifiedObject.next();
  const { value: valueOnDeepClone, done: doneOnDeepClone } = iteratorOnDeepClone.next();

  // 任意迭代器遍历完成即退出
  if (doneOnModifiedObject || doneOnDeepClone) {
    console.log("done!");
    break;
  }

  // 原有业务逻辑
  const { parent: parentOnDeepClone, node: nodeOnDeepClone, key: keyOnDeepClone, path: pathOnDeepClone, deep: deepOnDeepClone } = valueOnDeepClone;
  const { parent: parentOnModifiedObject, node: nodeOnModifiedObject, key: keyOnModifiedObject, path: pathOnModifiedObject, deep: deepOnModifiedObject } = valueOnModifiedObject;

  if (nodeOnModifiedObject.modifiedProperties != undefined) {
    for (const prop of nodeOnModifiedObject.modifiedProperties) {
      const oldValue = nodeOnDeepClone[prop];
      console.log(prop, oldValue);
    }
  }
}

方案3:优化实现逻辑避免同步问题

如果你的核心需求只是获取修改属性对应的旧值,不需要同时运行两个迭代器,只需要遍历修改后的对象,根据节点路径直接从旧对象中取值即可:

// 辅助函数:根据路径从对象中读取对应值
const getValueByPath = (obj: any, path: Array<string | number>) => {
  return path.reduce((current, key) => current?.[key], obj);
}

const traverseFilter = (node: any, key: string | number) => key !== 'modifiedProperties';
const iteratorOnModifiedObject = new RecursiveIterator(n, traverseFilter, true);

for (const { node, path } of iteratorOnModifiedObject) {
  if (!node.modifiedProperties) continue;
  const oldNode = getValueByPath(old, path);
  for (const prop of node.modifiedProperties) {
    console.log(prop, oldNode?.[prop]);
  }
}

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:18:02