调用导入的 class' 静态方法抛出 TypeError 错误
Calling imported class' static method throws a TypeError error
我试图从我创建的导入模块访问静态方法,但它导致抛出 TypeError 错误 - 说明该方法不存在。
我试过以不同的方式导出模块。如果我将它用作实例方法而不是静态方法,则可以调用该方法,但是它没有使用与 class 相关的任何内容,我认为它应该是静态的。
下面的静态方法:
(Bot.js)
const Bot = class Bot {
static getCommandIndex(message) {
if (!message.beginsWith('/')) {
return undefined;
}
return message.split(' ');
}
}
module.exports = Bot;
试图使用它的模块:
(BotUpdateHandler.js)
const Bot = require('./Bot');
module.exports = class BotUpdateHandler {
async handle(update) {
const txt = update.msg.txt;
const command = Bot.getCommandIndex(txt);
}
}
我已经尝试过像这样导出和导入模块:
// Exporting the module (Bot.js)
module.exports = { Bot };
// Importing the module (BotUpdateHandler.js)
const { Bot } = require('./Bot');
但效果不佳。
TypeError: Bot.getCommandIndex is not a function
我正在使用 Node.js v10.16.0,它似乎可以在浏览器上工作-JavaScript 当我在开发控制台中检查它时(显然我没有做任何导入所以我假设这与此有关)。
我认为你的模块定义没问题,但错误的是BotUpdateHandler
:
const Bot = require('./Bot');
module.exports = class BotUpdateHandler {
async handle(update) {
const command = Bot.getCommandIndex(txt);
}
}
Bot.getCommandIndex(txt)
使用 txt
参数调用,然后 Bot class 尝试在其上执行 beginsWith
方法,但 txt
未定义(可能是你想通过 var update
).
改变
所以 txt
上不存在的方法是 beginsWith
。
const Bot = require('./Bot');
module.exports = class BotUpdateHandler {
async handle(update) {
const command = Bot.getCommandIndex(update);
}
}
概览
所以我继续研究这个问题并试图找出问题的确切原因。
我来自 C# 世界,因此我习惯于在任何地方使用 using
语句,没有任何问题。但是,对于 NodeJS,您不能期望 require
与 using
语句的行为相同,因为 require
- 因为 require
需要时间来设置导出,如果您有两个相互依赖的模块 - 这将创建一种叫做 循环依赖性 .
的东西
解决方案
经过一些挖掘,我发现 this article and this 关于循环依赖的问题。最终,最好避免代码中存在循环依赖关系,就像上面链接问题的答案中所列的那样(有一个顶层模块管理两个模块之间共享的代码)。
不过,也有很多妙招可以解决这个问题。我使用的方法是在我需要静态方法之前使用 require
语句。
module.exports = class BotUpdateHandler {
handle(update) {
// eslint-disable-next-line global-require
const Bot = require('./Bot');
// code ....
const txt = update.text;
const command = Bot.getCommandIndex(txt);
}
}
此外,我发现您可以使用 madge.
检查您的代码是否存在循环依赖(以及许多其他有用的东西)
我试图从我创建的导入模块访问静态方法,但它导致抛出 TypeError 错误 - 说明该方法不存在。
我试过以不同的方式导出模块。如果我将它用作实例方法而不是静态方法,则可以调用该方法,但是它没有使用与 class 相关的任何内容,我认为它应该是静态的。
下面的静态方法: (Bot.js)
const Bot = class Bot {
static getCommandIndex(message) {
if (!message.beginsWith('/')) {
return undefined;
}
return message.split(' ');
}
}
module.exports = Bot;
试图使用它的模块: (BotUpdateHandler.js)
const Bot = require('./Bot');
module.exports = class BotUpdateHandler {
async handle(update) {
const txt = update.msg.txt;
const command = Bot.getCommandIndex(txt);
}
}
我已经尝试过像这样导出和导入模块:
// Exporting the module (Bot.js)
module.exports = { Bot };
// Importing the module (BotUpdateHandler.js)
const { Bot } = require('./Bot');
但效果不佳。
TypeError: Bot.getCommandIndex is not a function
我正在使用 Node.js v10.16.0,它似乎可以在浏览器上工作-JavaScript 当我在开发控制台中检查它时(显然我没有做任何导入所以我假设这与此有关)。
我认为你的模块定义没问题,但错误的是BotUpdateHandler
:
const Bot = require('./Bot');
module.exports = class BotUpdateHandler {
async handle(update) {
const command = Bot.getCommandIndex(txt);
}
}
Bot.getCommandIndex(txt)
使用 txt
参数调用,然后 Bot class 尝试在其上执行 beginsWith
方法,但 txt
未定义(可能是你想通过 var update
).
所以 txt
上不存在的方法是 beginsWith
。
const Bot = require('./Bot');
module.exports = class BotUpdateHandler {
async handle(update) {
const command = Bot.getCommandIndex(update);
}
}
概览
所以我继续研究这个问题并试图找出问题的确切原因。
我来自 C# 世界,因此我习惯于在任何地方使用 using
语句,没有任何问题。但是,对于 NodeJS,您不能期望 require
与 using
语句的行为相同,因为 require
- 因为 require
需要时间来设置导出,如果您有两个相互依赖的模块 - 这将创建一种叫做 循环依赖性 .
解决方案
经过一些挖掘,我发现 this article and this 关于循环依赖的问题。最终,最好避免代码中存在循环依赖关系,就像上面链接问题的答案中所列的那样(有一个顶层模块管理两个模块之间共享的代码)。
不过,也有很多妙招可以解决这个问题。我使用的方法是在我需要静态方法之前使用 require
语句。
module.exports = class BotUpdateHandler {
handle(update) {
// eslint-disable-next-line global-require
const Bot = require('./Bot');
// code ....
const txt = update.text;
const command = Bot.getCommandIndex(txt);
}
}
此外,我发现您可以使用 madge.
检查您的代码是否存在循环依赖(以及许多其他有用的东西)