Вызов статического метода импортированного класса вызывает ошибку TypeError - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь получить доступ к статическому методу из созданного мной импортированного модуля, но в результате возникает ошибка TypeError, указывающая, что метод не существует.

Я пыталсяэкспортировать модули по-разному.Метод может быть вызван, если я использую его как метод экземпляра, а не как статический, однако он не использует ничего, связанного с классом, и я думаю, что он должен быть статическим.

Следующий статический метод:( 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);
  }
}

I 'Мы уже пытались экспортировать и импортировать модули следующим образом:

// 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 браузера, когда я проверил его в консоли разработчика (очевидно, хотя я не делал никаких импортов, поэтому я предполагаю, что это как-то связано с этим).

Ответы [ 2 ]

0 голосов
/ 22 июня 2019

Обзор

Поэтому я продолжил исследовать проблему и попытался выяснить, в чем именно заключается проблема.

Я родом из мира C #, и поэтому я привык иметь повсюду using операторы без проблем. Однако с NodeJS вы не можете ожидать, что require будет вести себя так же, как оператор using с require - потому что require требует времени для настройки экспорта, и если у вас есть два модуля, зависящих друг от друга - это создаст нечто под названием циклические зависимости .

Решение

После некоторого поиска я нашел эту статью и этот вопрос о циклических зависимостях. В конечном итоге лучше избегать циклических зависимостей в вашем коде , как указано в ответах на связанный вопрос выше (наличие верхнего модуля, который управляет кодом, разделяемым между двумя модулями).

Однако, есть также много хитрых приемов для преодоления этой проблемы. Я использовал оператор 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 .

0 голосов
/ 14 июня 2019

Я думаю, что ваше определение модуля в порядке, но что это не так: BotUpdateHandler:


    const Bot = require('./Bot');
    module.exports = class BotUpdateHandler {
      async handle(update) {
        const command = Bot.getCommandIndex(txt);
      }
    }

Bot.getCommandIndex(txt) вызывается с параметром txt, а затем класс Bot пытается выполнить для него метод beginsWith, но txt не определено (возможно, вы хотите изменить его с помощью переменной update).

Таким образом, метод, который не существует, это beginsWith на txt.

    const Bot = require('./Bot');
    module.exports = class BotUpdateHandler {
      async handle(update) {
        const command = Bot.getCommandIndex(update);
      }
    }

...