Я понял, что в книге вы не хотите вводить слишком много вещей сразу, и автор должен был сделать несколько ярлыков, но если ваш код ожидает, что что-то будет массивом, он должен на самом деле проверить (или иметьстатическая проверка типов), что это на самом деле массив.Метод getBooks
должен быть переписан следующим образом:
static getBooks () {
const stored = localStorage.getItem('books');
let books = []; // default to empty array
// need the try-catch here because the parse can fail
try {
const parsed = JSON.parse(stored);
if (Array.isArray(parsed)) { // check that it's an array
books = parsed;
} // else leave books as default
} catch (e) {
// no-op, leave books as default
}
return books;
}
Теперь код будет
- Всегда возвращать массив и ничего больше
- Всегда успешно.Существует очень строгое соглашение, что метод получения никогда не должен генерировать, и в исходном методе анализ может завершиться неудачно.
Если вы занимаетесь бессмысленной микрооптимизацией, вы также можете добавить ранний возврат, чтобы пропустить try/catch
, если stored
равно null
или undefined
.
Оригинал почти наверняка дает сбой, потому что произошло нечто подобное:
localStorage.setItem('books', JSON.stringify({})); // NOTE: {} not []
Теперь, когда он найден:
if (localStorage.getItem('books') === null) { // this will be false, because it's not null
Потом позже
books.push(whatever); // oops! books is {} not []! No push method for you
Что объясняетпочему обновление не исправляет это, и почему один и тот же код прекрасно работает на другой странице (например, в коде).Если вы откроете консоль на этой странице и наберете localStorage.setItem('books', '[]')
, вы можете внезапно увидеть, что ваша проблема исчезла.