Почему localStorage не работает с объектами (и как это исправить)
Вы когда-нибудь пытались сохранить объект в localStorage и получали вместо него строку "[object Object]"? Если да — вы не одиноки. Этот вопрос на Stack Overflow собрал тысячи просмотров, и сегодня мы раз и навсегда разберемся, как правильно хранить объекты в HTML5 веб-хранилище.
Дело в том, что localStorage и sessionStorage умеют работать только с строками. Когда вы пишете:
localStorage.setItem('user', {name: 'Анна', age: 25});
JavaScript автоматически вызывает метод .toString() у объекта, и на выходе получается бесполезная строка. Но есть проверенный способ обойти это ограничение — сериализация через JSON.
Что такое сериализация и зачем она нужна
Сериализация — это процесс преобразования сложной структуры данных (объекта, массива) в строку, которую можно сохранить или передать. Обратный процесс называется десериализацией (превращение строки обратно в объект).
В JavaScript за это отвечают два метода:
JSON.stringify()— превращает объект в строку JSONJSON.parse()— превращает строку JSON обратно в объект
Именно эти методы — ключ к решению проблемы хранения объектов в localStorage и sessionStorage.
Пошаговый туториал: сохраняем объект в localStorage
Шаг 1. Создаем объект
const user = {
id: 101,
name: 'Мария',
email: 'maria@example.com',
preferences: {
theme: 'dark',
notifications: true
},
tags: ['javascript', 'react', 'python']
};
Шаг 2. Сериализуем в JSON
const userJSON = JSON.stringify(user);
console.log(userJSON);
// {"id":101,"name":"Мария","email":"maria@example.com","preferences":{"theme":"dark","notifications":true},"tags":["javascript","react","python"]}
Шаг 3. Сохраняем в localStorage
localStorage.setItem('currentUser', userJSON);
Шаг 4. Извлекаем и десериализуем
const savedUserJSON = localStorage.getItem('currentUser');
const savedUser = JSON.parse(savedUserJSON);
console.log(savedUser.name); // Мария
console.log(savedUser.preferences.theme); // dark
console.log(savedUser.tags[0]); // javascript
Вот и всё! Теперь у вас есть полноценный объект со всеми вложенными структурами.
sessionStorage: то же самое, но с нюансом
sessionStorage работает абсолютно идентично localStorage, но с одним важным отличием: данные живут только до закрытия вкладки. Как только вы закрываете браузерную вкладку — всё удаляется.
// Сохраняем
sessionStorage.setItem('tempData', JSON.stringify({step: 3, progress: '75%'}));
// Извлекаем
const temp = JSON.parse(sessionStorage.getItem('tempData'));
console.log(temp.progress); // 75%
Используйте sessionStorage для временных данных: состояние формы, шаги мастера настройки, одноразовые токены.
Типичные ошибки и как их избежать
Ошибка 1: Забыли парсить
const data = localStorage.getItem('myObject');
console.log(data.name); // undefined — потому что data это строка!
Решение: всегда используйте JSON.parse() после получения данных.
Ошибка 2: Сохраняете undefined или функции
const obj = { name: 'Alex', greet: function() { return 'Hi!'; } };
localStorage.setItem('test', JSON.stringify(obj)); // функция потеряется
Решение: JSON.stringify не сохраняет функции, undefined, Symbol и циклические ссылки. Храните только данные.
Ошибка 3: Не проверяете на null
const item = JSON.parse(localStorage.getItem('nonExistentKey')); // null
console.log(item.someProperty); // Ошибка! Cannot read property of null
Решение: всегда проверяйте, что данные существуют:
const raw = localStorage.getItem('myKey');
const data = raw ? JSON.parse(raw) : null;
// или с использованием fallback
const data = JSON.parse(localStorage.getItem('myKey') || 'null');
Продвинутые техники работы с веб-хранилищем
Хранение массивов объектов
const users = [
{ id: 1, name: 'Иван' },
{ id: 2, name: 'Ольга' },
{ id: 3, name: 'Петр' }
];
localStorage.setItem('users', JSON.stringify(users));
// Извлекаем
const savedUsers = JSON.parse(localStorage.getItem('users'));
savedUsers.forEach(user => console.log(user.name));
Обновление части данных
// Получаем, изменяем, сохраняем обратно
let settings = JSON.parse(localStorage.getItem('appSettings') || '{}');
settings.language = 'ru';
settings.fontSize = 16;
localStorage.setItem('appSettings', JSON.stringify(settings));
Удаление данных
// Удалить один ключ
localStorage.removeItem('tempData');
// Очистить всё хранилище
localStorage.clear();
Ограничения localStorage и sessionStorage
- Лимит: обычно 5-10 МБ на домен (зависит от браузера)
- Только строки: поэтому и нужен JSON
- Синхронность: операции блокируют основной поток
- Безопасность: не храните пароли, токены доступа или чувствительные данные
Когда использовать localStorage, а когда sessionStorage?
| localStorage | sessionStorage |
|---|---|
| Настройки пользователя (тема, язык) | Данные формы (черновик) |
| Кеш данных (список товаров) | Состояние игры (до конца сессии) |
| История действий | Временные флаги (первый визит) |
| Данные корзины (долгосрочно) | OAuth state параметры |
Проверка поддержки браузером
function isStorageAvailable(type) {
let storage;
try {
storage = window[type];
const x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch (e) {
return false;
}
}
if (isStorageAvailable('localStorage')) {
// Можно использовать localStorage
} else {
console.warn('localStorage недоступ