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
相关产品推荐
相关产品推荐

