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

如何在递归函数中调用另一个递归函数?解决TypeScript递归函数嵌套调用的undefined错误

解决递归函数调用中的cannot read property 'date' of undefined错误

让我们一步步拆解你的问题,找出核心问题并逐一修复:

1. 触发错误的根本原因:this指向丢失

你遇到的cannot read property 'date' of undefined错误,本质是在递归调用过程中this的指向变成了undefined,导致无法访问类实例的date方法。这种情况通常发生在类方法没有正确绑定实例this,或者方法被当作普通函数调用时。

修复方案:稳定this指向

有两种简单的方式确保this始终指向类实例:

  • 用箭头函数定义类方法:箭头函数会自动绑定当前实例的this,彻底避免指向丢失:
export class FormFiller {
  fill = (index = 0): any => {
    // 原fill方法逻辑不变
  }

  date = (qid: string, val?: string): any => {
    // 原date方法逻辑不变
  }
}
  • 在构造函数中手动绑定this:
export class FormFiller {
  constructor() {
    this.fill = this.fill.bind(this);
    this.date = this.date.bind(this);
  }

  fill(index = 0): any { /* ... */ }
  date(qid: string, val?: string): any { /* ... */ }
}

2. 修复date方法的逻辑错误

除了this的问题,你的代码还有几个明显的逻辑漏洞,会导致后续报错:

  • 未定义的el变量:date方法里的$(el)是笔误,应该使用传入的qid参数来选择元素,即$(qid),否则根本找不到目标DOM元素。
  • 缺少必填参数:fill方法调用this.date()时,没有传递date要求的第一个参数qid,导致qid为undefined。你需要根据index传入对应的qid,比如维护一个qid列表:
// 假设你有需要处理的qid列表
private qids = ['input-1', 'input-2', 'input-3'];

fill(index = 0): any {
  // 增加递归终止条件:遍历完所有qid
  if (index >= this.qids.length) {
    console.log('所有元素处理完成');
    return;
  }
  
  const qid = this.qids[index];
  const fillTypeFunction = this.date(qid); // 传入必填的qid参数
  
  if (fillTypeFunction) {
    fillTypeFunction('arg1', 'arg2');
  } else {
    console.warn(`无法获取元素处理函数,跳过qid: ${qid}`);
  }
  
  return this.fill(index + 1);
}
  • date方法无返回值:当前date方法没有返回任何值,导致fillTypeFunction永远是undefined,会触发else分支的错误。如果你期望它返回可调用的处理函数,需要调整逻辑:
date(qid: string, val?: string): ((arg1: string, arg2: string) => void) | undefined {
  const elem = $(qid);
  // 先检查元素是否存在
  if (!elem.length) {
    console.error(`找不到目标元素:${qid}`);
    return undefined;
  }

  if (elem.attr('ng-reflect-value')) {
    console.log(`元素${qid}已有值`);
    // 返回实际执行填充的函数
    return (_, value) => {
      elem.val(value);
      console.log(`填充元素${qid}为:${value}`);
    };
  } else {
    // 用定时器延迟递归,避免同步递归导致栈溢出
    setTimeout(() => {
      this.date(qid, val);
    }, 200);
    return undefined;
  }
}
  • 无限递归风险:原date方法没有终止条件,如果元素一直没有ng-reflect-value属性,会无限递归导致栈溢出。添加定时器延迟递归是一种缓解方式,你也可以增加递归次数限制来彻底避免。

3. 完整修复后的代码示例

export class FormFiller {
  private qids = ['input-1', 'input-2', 'input-3'];

  constructor() {
    this.fill = this.fill.bind(this);
    this.date = this.date.bind(this);
  }

  fill(index = 0): any {
    if (index >= this.qids.length) {
      console.log('所有元素填充完成');
      return;
    }

    const qid = this.qids[index];
    const fillTypeFunction = this.date(qid);
    
    if (fillTypeFunction) {
      fillTypeFunction('arg1', 'sample-value');
    } else {
      console.warn(`跳过元素${qid}:无法获取处理函数`);
    }

    return this.fill(index + 1);
  }

  date(qid: string, val?: string): ((arg1: string, arg2: string) => void) | undefined {
    const elem = $(qid);
    if (!elem.length) {
      console.error(`元素${qid}不存在`);
      return undefined;
    }

    if (elem.attr('ng-reflect-value')) {
      return (_, value) => {
        elem.val(value);
        console.log(`元素${qid}填充完成,值为:${value}`);
      };
    } else {
      setTimeout(() => {
        this.date(qid, val);
      }, 200);
      return undefined;
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:57:41