localStorage и sessionStorage в JavaScript: понятное практическое руководство
Зачем нужен Web Storage и чем полезен localStorage в JavaScript
Web Storage API даёт два простых механизма для хранения данных на стороне клиента: localStorage и sessionStorage. Оба — это ключ‑значение (только строки), синхронные, очень быстрые и не требуют сервера. Классические сценарии: сохранение темы оформления, последнего открытого шага мастера, содержимого корзины, флагов «уже показывал подсказку» и др.
- localStorage — общая «память» для домена. Данные живут между перезапусками браузера, до явного удаления.
- sessionStorage — память текущей вкладки. Очищается при закрытии вкладки (или вкладочного контекста).
Быстрый старт: основные операции
// Сохранить строку
localStorage.setItem('theme', 'dark');
// Прочитать
const theme = localStorage.getItem('theme'); // 'dark'
// Удалить ключ
localStorage.removeItem('theme');
// Очистить всё хранилище текущего домена
localStorage.clear();
// Количество записей
console.log(localStorage.length);
У sessionStorage тот же API: setItem, getItem, removeItem, clear и свойство length.
Хранение объектов: JSON.stringify и JSON.parse
Web Storage хранит только строки. Для объектов используйте JSON:
const user = { id: 42, name: 'Alice', roles: ['admin', 'author'] };
localStorage.setItem('user', JSON.stringify(user));
try {
const parsed = JSON.parse(localStorage.getItem('user'));
console.log(parsed.name); // 'Alice'
} catch (e) {
console.warn('Некорректный JSON в localStorage');
}
Совет: добавляйте неймспейсы к ключам (например, app:cart), чтобы избежать конфликтов с чужими скриптами того же домена.
Проверка доступности и обработка исключений
В приватных режимах, при политике безопасности или переполнении квоты операции могут бросать исключения. Делайте защитные проверки:
const storageAvailable = (() => {
try {
const k = '__test__' + Math.random();
localStorage.setItem(k, '1');
localStorage.removeItem(k);
return true;
} catch (_) {
return false;
}
})();
function safeSet(key, value) {
if (!storageAvailable) return false;
try {
localStorage.setItem(key, value);
return true;
} catch (e) {
console.warn('Не удалось записать в localStorage:', e);
return false;
}
}
Лимиты обычно 5–10 МБ на домен. Не храните большие бинарные строки и чувствительные данные (логины, токены).
TTL (время жизни): делаем «устаревающие» записи
По умолчанию записи не имеют срока жизни. Добавим TTL вручную — пригодится для кэшей запросов или баннеров «показать раз в сутки».
function saveWithTTL(key, value, ttlMs) {
const payload = { value, expires: Date.now() + ttlMs };
localStorage.setItem(key, JSON.stringify(payload));
}
function loadWithTTL(key) {
const raw = localStorage.getItem(key);
if (!raw) return null;
try {
const data = JSON.parse(raw);
if (data.expires && Date.now() > data.expires) {
localStorage.removeItem(key);
return null;
}
return data.value;
} catch (_) {
return null;
}
}
// Пример: кэш ответа на 10 минут
saveWithTTL('news:list', [{ id: 1, title: 'Hi' }], 10 * 60 * 1000);
const cached = loadWithTTL('news:list');
Удобная обёртка с неймспейсом
Мини‑хелпер, который сериализует/десериализует и избегает конфликтов ключей:
function createStore(prefix = 'app:') {
return {
set(key, val) {
localStorage.setItem(prefix + key, JSON.stringify(val));
},
get(key, fallback = null) {
const raw = localStorage.getItem(prefix + key);
if (raw === null) return fallback;
try { return JSON.parse(raw); } catch (_) { return fallback; }
},
remove(key) {
localStorage.removeItem(prefix + key);
}
};
}
const store = createStore('demo:');
store.set('settings', { theme: 'dark' });
console.log(store.get('settings')); // { theme: 'dark' }
Синхронизация между вкладками: событие storage
Когда одна вкладка меняет localStorage, другие вкладки того же домена получают событие storage. Это удобно, чтобы синхронизировать тему, авторизацию, фичефлаги.
// Синхронизация темы между вкладками
window.addEventListener('storage', (e) => {
if (e.key === 'theme') {
document.documentElement.dataset.theme = e.newValue || 'light';
}
});
// Где-то в UI:
function toggleTheme() {
const cur = localStorage.getItem('theme') === 'dark' ? 'light' : 'dark';
localStorage.setItem('theme', cur);
}
Важно: событие не срабатывает в той вкладке, где изменение произошло, — только в других открытых вкладках/окнах.
Чем sessionStorage отличается на практике
sessionStorage изолирован по вкладкам. Хорош для временных черновиков форм, состояний мастера или «реферальных» меток в рамках одного визита:
// Счётчик действий для этой вкладки
const clicks = Number(sessionStorage.getItem('clicks') || 0) + 1;
sessionStorage.setItem('clicks', String(clicks));
console.log('Кликов в этой вкладке:', clicks);
// Метка вкладки (удобно для отладки)
if (!sessionStorage.getItem('tabId')) {
sessionStorage.setItem('tabId', (crypto?.randomUUID?.() || Date.now().toString(36)));
}
Безопасность и ограничения
- Не храните секреты (токены, пароли). При XSS злоумышленник прочитает Web Storage.
- Объём ограничен, API синхронный — не кладите большие данные и не вызывайте операции в горячих циклах рендера.
- Данные доступны только тому же протоколу/домену/порту.
Чек‑лист лучших практик
- Используйте неймспейсы в ключах:
app:feature:flag. - Сериализуйте через JSON и обрабатывайте ошибки
JSON.parse. - Добавляйте TTL для кэшей и временных данных.
- Проверяйте доступность хранилища и ловите исключения квоты.
- Синхронизируйте важные состояния через событие
storage. - Не храните чувствительные данные, позаботьтесь о защите от XSS.
Итоги
localStorage в JavaScript — простой и мощный инструмент для клиентского состояния, а sessionStorage идеален для данных в рамках одной вкладки. Используйте JSON, TTL‑паттерн, неймспейсы и событие storage — так вы получите быстрый, предсказуемый и устойчивый к ошибкам слой хранения.
Хотите уверенно применять эти техники в реальных проектах и закрепить всё на практике? Загляните в курс Полный практический путь по JavaScript: от нуля до уверенного уровня — много задач, разборов и проектов для прокачки навыков.
-
Создано 16.01.2026 17:02:06
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.