Avatar ·

Как сохранить объекты JavaScript в localStorage или sessionStorage?

Всем привет! Я начинающий frontend-разработчик и столкнулся с такой проблемой: пытаюсь сохранить объект в localStorage, но вместо данных получаю строку "[object Object]". Вот мой код: ```javascript const user = { name: 'Алексей', age: 28, isAdmin: true }; localStorage.setItem('currentUser', user); const savedUser = localStorage.getItem('currentUser'); console.log(savedUser); // Выводит "[object Object]" ``` Я ожидал, что сохраню объект целиком и потом смогу его использовать как обычный объект, но localStorage, похоже, работает только со строками. Как правильно сохранять и извлекать объекты? Нужно ли использовать JSON? И как быть с вложенными объектами или массивами? Также интересует, есть ли ограничения по размеру данных? У меня в проекте планируется сохранять довольно сложные структуры данных (например, корзину товаров с вложенными объектами товаров). Заранее спасибо за помощь! <<>>

Правильное сохранение объектов в localStorage с помощью JSON

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

Базовое решение

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

// Сохранение
const user = {
  name: 'Алексей',
  age: 28,
  isAdmin: true
};

localStorage.setItem('currentUser', JSON.stringify(user));

// Извлечение
const savedUser = JSON.parse(localStorage.getItem('currentUser'));
console.log(savedUser.name); // "Алексей"
console.log(savedUser.age);  // 28

Работа с вложенными объектами и массивами

JSON поддерживает любую вложенность объектов и массивов. Вот пример с корзиной товаров:

const cart = {
  items: [
    { id: 1, name: 'Ноутбук', price: 75000, quantity: 1 },
    { id: 2, name: 'Мышь', price: 1500, quantity: 2 }
  ],
  totalPrice: 78000,
  lastUpdated: new Date().toISOString()
};

// Сохраняем
localStorage.setItem('shoppingCart', JSON.stringify(cart));

// Извлекаем
const restoredCart = JSON.parse(localStorage.getItem('shoppingCart'));
console.log(restoredCart.items[0].name); // "Ноутбук"
console.log(restoredCart.totalPrice);    // 78000

Обработка ошибок и проверка существования

Всегда проверяйте, что данные существуют, и оборачивайте парсинг в try-catch:

function getFromStorage(key) {
  try {
    const data = localStorage.getItem(key);
    return data ? JSON.parse(data) : null;
  } catch (error) {
    console.error('Ошибка при парсинге данных из localStorage:', error);
    return null;
  }
}

function saveToStorage(key, value) {
  try {
    localStorage.setItem(key, JSON.stringify(value));
    return true;
  } catch (error) {
    console.error('Ошибка при сохранении в localStorage:', error);
    return false;
  }
}

// Использование
saveToStorage('user', { name: 'Иван' });
const userData = getFromStorage('user');

Ограничения по размеру

Размер localStorage обычно ограничен 5-10 МБ на домен (зависит от браузера). Для больших объёмов данных используйте IndexedDB. Также помните:

  • sessionStorage очищается при закрытии вкладки
  • localStorage хранится постоянно до явного удаления
  • Данные хранятся в виде строк — JSON.stringify увеличивает размер из-за кавычек и служебных символов

Важные нюансы при работе с JSON

Некоторые типы данных не поддерживаются JSON:

  • Функции — будут удалены при сериализации
  • undefined — превращается в null или удаляется из объекта
  • Date — преобразуется в строку (используйте new Date(restored.date) при восстановлении)
  • Map, Set — не поддерживаются, нужно преобразовывать в массивы

Пример работы с датами:

const data = {
  timestamp: new Date().toISOString()  // сохраняем как строку
};

localStorage.setItem('time', JSON.stringify(data));
const restored = JSON.parse(localStorage.getItem('time'));
const date = new Date(restored.timestamp); // восстанавливаем объект Date
<<>>

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

Для упрощения работы можно создать небольшой класс-обёртку, который автоматически обрабатывает сериализацию и предоставляет удобный интерфейс:

class StorageManager {
  constructor(storage = localStorage) {
    this.storage = storage;
  }

  get(key) {
    try {
      const value = this.storage.getItem(key);
      return value ? JSON.parse(value) : null;
    } catch {
      return null;
    }
  }

  set(key, value) {
    try {
      this.storage.setItem(key, JSON.stringify(value));
      return true;
    } catch {
      return false;
    }
  }

  remove(key) {
    this.storage.removeItem(key);
  }

  clear() {
    this.storage.clear();
  }

  has(key) {
    return this.storage.getItem(key) !== null;
  }
}

// Использование
const store = new StorageManager();

// Сохраняем
store.set('settings', { theme: 'dark', fontSize: 14 });

// Извлекаем
const settings = store.get('settings');
console.log(settings.theme); // "dark"

// Проверяем наличие
if (store.has('settings')) {
  console.log('Настройки найдены');
}

Такой подход особенно удобен, если в проекте много операций с хранилищем. Вы можете легко расширить класс, добавив, например, методы для работы со временем жизни данных или автоматическую очистку устаревших записей. Также можно легко переключиться между localStorage и sessionStorage, просто передав нужный объект в конструктор.