Avatar ·

Как сохранить и прочитать объекты JavaScript в localStorage / sessionStorage

Всем привет. Я новичок в JavaScript и пытаюсь сохранить объект в localStorage, чтобы данные оставались после перезагрузки страницы. Пишу небольшое приложение — список задач (todo list). Каждая задача — это объект с полями: `{ id: 1, text: "Купить молоко", done: false }`. Я пробую сохранить массив таких объектов так: ```javascript const tasks = [ { id: 1, text: "Купить молоко", done: false }, { id: 2, text: "Позвонить врачу", done: true } ]; localStorage.setItem('myTasks', tasks); ``` Потом пытаюсь прочитать: ```javascript const saved = localStorage.getItem('myTasks'); console.log(saved); ``` В консоли вижу `[object Object],[object Object]`. Это не массив, а какая-то странная строка. Если я вывожу `typeof saved`, то получаю `string`. Я не могу обратиться к свойствам объектов, например `saved[0].text` — выдаёт `undefined`. Я читал, что localStorage хранит только строки. Но как тогда правильно сохранять объекты? Нужно ли их как-то превращать в строку, а потом обратно? Подскажите, пожалуйста, как это сделать правильно, с примерами. Заранее спасибо! <<>>

Проблема: localStorage хранит только строки

Вы совершенно правы — localStorage и sessionStorage могут хранить данные исключительно в текстовом формате (строки). Когда вы пытаетесь сохранить объект или массив, JavaScript автоматически вызывает у него метод .toString(), который для объектов возвращает бесполезную строку [object Object].

Решение: используем JSON-сериализацию

Чтобы сохранить объект, его нужно сначала преобразовать в JSON-строку с помощью JSON.stringify(), а при чтении — обратно в объект с помощью JSON.parse().

Вот правильный код для вашего примера с задачами:

// Сохранение
const tasks = [
  { id: 1, text: "Купить молоко", done: false },
  { id: 2, text: "Позвонить врачу", done: true }
];

localStorage.setItem('myTasks', JSON.stringify(tasks));

// Чтение
const savedTasks = JSON.parse(localStorage.getItem('myTasks'));
console.log(savedTasks); // [ { id: 1, text: "Купить молоко", done: false }, ... ]
console.log(savedTasks[0].text); // "Купить молоко"

Важные нюансы

  • Проверка на null: Если ключа в хранилище нет, getItem возвращает null. Передавать null в JSON.parse() нельзя — будет ошибка. Всегда проверяйте:
const data = localStorage.getItem('myTasks');
const tasks = data ? JSON.parse(data) : []; // если данных нет, используем пустой массив
  • Лимит хранилища: Обычно localStorage выделяет около 5-10 МБ на домен. Если ваш объект слишком большой, JSON-строка может не поместиться — тогда setItem выбросит исключение QuotaExceededError. Оборачивайте сохранение в try/catch.
  • Несохраняемые типы: JSON поддерживает только: строки, числа, булевы значения, null, массивы и простые объекты. Функции, undefined, Symbol, Date (превратится в строку), Map, Set и циклические ссылки не сохраняются корректно. Для дат используйте date.toISOString() при сохранении и new Date(str) при чтении.
  • sessionStorage: Работает абсолютно так же, но данные живут только до закрытия вкладки. Если нужно — просто замените localStorage на sessionStorage.

Полный пример для todo-приложения

// --- Сохранение ---
function saveTasks(tasksArray) {
  try {
    localStorage.setItem('myTasks', JSON.stringify(tasksArray));
  } catch (e) {
    console.error('Не удалось сохранить задачи:', e);
  }
}

// --- Загрузка ---
function loadTasks() {
  const stored = localStorage.getItem('myTasks');
  return stored ? JSON.parse(stored) : [];
}

// Использование
let tasks = loadTasks(); // загружаем при старте
tasks.push({ id: Date.now(), text: "Новая задача", done: false });
saveTasks(tasks); // сохраняем после изменений

Теперь ваши объекты будут сохраняться и восстанавливаться корректно. Удачи в разработке!

<<>>

Альтернативный подход: библиотека-обёртка

Если вы работаете с большим количеством сложных данных или не хотите каждый раз писать JSON.stringify/parse, можно использовать небольшую вспомогательную функцию или готовую библиотеку, например store.js (всего 2 КБ).

Пример с store.js:

// Подключаем: <script src="store.min.js"></script>

// Сохраняем — библиотека сама сериализует
store.set('tasks', [
  { id: 1, text: "Купить молоко", done: false }
]);

// Читаем — библиотека сама десериализует
const tasks = store.get('tasks');
console.log(tasks[0].text); // "Купить молоко"

Библиотека автоматически обрабатывает JSON, проверяет на null, и даже поддерживает устаревшие браузеры (IE8+). Если не хотите подключать внешние зависимости — просто сделайте свою обёртку:

const storage = {
  set(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  },
  get(key) {
    const item = localStorage.getItem(key);
    return item ? JSON.parse(item) : null;
  },
  remove(key) {
    localStorage.removeItem(key);
  }
};

// Использование
storage.set('user', { name: 'Анна', age: 30 });
const user = storage.get('user');

Такой подход делает код чище и снижает риск ошибок с null.