TL; DR - Супер-ключевое слово в моем объявлении класса иногда (но не всегда) не определено. Как / почему?
У меня есть следующее объявление класса, расширяющее Array
, используемое для данных результатов поиска из API:
class SearchResult extends Array {
constructor(resultArray) {
super(...resultArray);
}
static createFromApiData(apiData) {
const resultArray = apiData.filter(...).map(...);
return new SearchResult(resultArray);
}
...otherMethods
}
В моем приложении это первоначально вызывается сразу после получения ответа от API, как показано ниже:
apiCall().then((res) => {
const searchResults = SearchResult.createFromApiData(res.data);
});
Создание нового экземпляра SearchResult
с использованием этого статического метода работает правильно, возвращая то, что я хочу.
Однако позже в моем приложении мне нужно снова создать экземпляр SearchResult
, на этот раз нет необходимости в вызове API, поскольку у меня уже есть данные resultArray
, хранящиеся в базе данных. Поэтому второй раз я пытаюсь создать экземпляр SearchResult
, используя ключевое слово new
, как показано ниже:
const searchResults = new SearchResult(resultArray);
На этот раз при использовании ключевого слова new
создание экземпляра завершается неудачно и выдает следующую ошибку:
TypeError: undefined is not a function at new SearchResult
Я знаю, undefined
в этом контексте ссылается на ключевое слово super
, но я не могу понять, почему это так? Как может изменяться поведение создания экземпляра в этих двух случаях? Как я могу это исправить?
UPDATE
Я продолжил расследование и обнаружил следующее. Первоначальная проблема была вызвана тем, что я сохранял свой экземпляр класса SearchResult
в базе данных ( dynamicodb ). Хотя SearchResult
расширенный массив, ddb сохранил его как базовый объект, поэтому при извлечении данных из базы данных он поступал в виде базового объекта, а не в виде массива. Это затем выдало ошибку, когда я попытался распространить объект внутри функции super
.
Я решил эту проблему путем распространения экземпляра моего класса в новом массиве при сохранении его в ddb :
db.save([...searchResults]);
Возвращает массив после вызова базы данных и может быть успешно распространен внутри вызова super
.
Однако это привело к новой проблеме. Сразу после создания нового экземпляра SearchResult
я вызываю следующий пользовательский метод:
nextItem() {
this.splice(0, 1);
return this[0];
}
Затем этот метод снова вызывает super
для доступа к методу splice
в Array
. Тем не менее, снова это не удается, выдавая ту же ошибку, что и раньше:
{
"errorMessage": "undefined is not a function",
"errorType": "TypeError",
"stackTrace": [
"new SearchResult",
"SearchResult.splice",
"SearchResult.nextRecipe"
}
Еще раз это относится к операции распространения внутри super
. На этот раз super
передается число 1
в качестве единственного аргумента. Откуда это 1
и как я могу это исправить?
ОБНОВЛЕНИЕ 2
После обновления метода класса до нас shift
вместо splice
метод теперь работает без ошибок. Моя проблема теперь эффективно решена, однако я все равно буду благодарен за понимание того, что проблема с super
, вызванная с 1
, была связана с splice
. Почему эти два метода массива ведут себя по-разному в этом контексте.
nextItem() {
return this.shift();
}