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

JavaScript类间递归调用报错:TypeError: Lexer is not a constructor

类间递归方法调用导致的TypeError问题解决

问题描述

我在两个文件中分别定义了Lexer和Quote类,想要实现类间的递归方法调用,但运行JavaScript代码时出现了错误。

相关代码

lexer/index.js

const Quote = require('./tokenizer/quote.js')
module.exports = class Lexer {

  constructor(args) {
    // 一些get/set方法调用
  }
  
  run () {
    return Quote.tokenize(args)
  }
}

lexer/tokenizer/quote.js

const Lexer = require('../index')
module.exports = class Quote {
  // 无构造函数,也可以添加

  static tokenize(args) {
    // 一些body相关计算
    // 再次调用lexer的run方法
    const quoteLexer = new Lexer(body)
    return quoteLexer.run()
  }
}

index.js

const Lexer = require("./lexer")
const l = new Lexer(someContent)
console.log(l.run())

运行错误

> node index.js

/home/kiran/dev/markdown-parser/lib/lexer/tokenizer/quote.js:57
    const quoteLexer = new Lexer(body)
                       ^

TypeError: Lexer is not a constructor
    at Function.tokenize (/home/kiran/dev/markdown-parser/lib/lexer/tokenizer/quote.js:57:24)

复现步骤

执行命令:npm install && npm run convert

问题原因与解决方法

这是循环引用导致的问题:
当lexer/index.js加载quote.js时,quote.js又反过来加载lexer/index.js,此时lexer/index.js还未完成导出,所以quote.js中拿到的Lexer是一个空对象,而非构造函数。

方法一:延迟引入

将quote.js中的Lexer引用延迟到函数内部,避免模块加载阶段的循环引用:
修改lexer/tokenizer/quote.js:

module.exports = class Quote {
  static tokenize(args) {
    // 一些body相关计算
    // 延迟引入,避免循环引用
    const Lexer = require('../index')
    const quoteLexer = new Lexer(body)
    return quoteLexer.run()
  }
}

方法二:重构代码消除循环依赖

把两个类中相互调用的逻辑抽离到第三方模块,或者调整类的职责,避免直接的循环引用。比如可以将递归调用的逻辑封装成独立的工具函数,供两个类调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:54:27