localStorage в JavaScript — руководство и проект счётчика

Что такое localStorage в JavaScript
localStorage — часть Web Storage API, поддерживаемого современными браузерами. Это простое хранилище ключ—значение, где и ключи, и значения хранятся как строки в формате UTF-16 DOM String. Данные сохраняются между сессиями браузера и доступны любым окнам и вкладкам с тем же origin.
Ключевая особенность: localStorage синхронен. Это значит, операции чтения и записи блокируют основной поток выполнения JavaScript на момент выполнения. Для небольших записей это не проблема, но для больших объёмов и частых операций стоит рассмотреть асинхронные альтернативы (IndexedDB).
Определение в одну строку: localStorage — это персистентное локальное хранилище ключ—значение в браузере, доступное в рамках origin.
Ключевые свойства и ограничения:
- Вместимость: обычно около 5 МБ в браузерах по умолчанию. Точное значение зависит от браузера и платформы.
- Доступность: данные остаются после закрытия вкладки или браузера.
- Домен: разделяется по origin (схема + хост + порт).
- Безопасность: данные доступны всем скриптам с тем же origin, поэтому нельзя хранить секреты.
- API: простые методы setItem, getItem, removeItem, clear; свойство length и метод key(index).
localStorage и sessionStorage
Оба API — часть Web Storage. Основное различие:
- localStorage: данные сохраняются постоянно, пока не будут удалены вручную или программно.
- sessionStorage: данные живут только в пределах одной сессии вкладки. После закрытия вкладки данные исчезают.
Используйте sessionStorage для временных данных, которые не должны быть доступны после закрытия вкладки. Используйте localStorage для настроек пользователя, состояния UI и других не чувствительных, но долгоживущих значений.
Как работает localStorage
Объект доступен через window.localStorage. Основные методы:
- setItem(key, value) — сохраняет строковое значение по ключу.
- getItem(key) — возвращает строку или null при отсутствии ключа.
- removeItem(key) — удаляет пару ключ—значение.
- clear() — очищает всё хранилище для текущего origin.
- length — число пар в хранилище.
- key(index) — возвращает ключ по индексу.
Важно: если нужно хранить объекты или массивы, предварительно сериализуйте их в JSON: JSON.stringify() при записи и JSON.parse() при чтении.
Пример записи простого значения
window.localStorage.setItem('Python', 'Guido van Rossum');Пример записи объекта и массива
const student = {
name: 'Yuvraj',
marks: 85,
subject: 'Machine Learning'
};
const scores = [76, 77, 34, 67, 88];
window.localStorage.setItem('result', JSON.stringify(student));
window.localStorage.setItem('marks', JSON.stringify(scores));Чтение данных
let data1 = window.localStorage.getItem('Python');
let data2 = window.localStorage.getItem('result');
console.log(data1);
console.log(data2);Вывод будет таким:
Guido van Rossum
{"name":"Yuvraj","marks":85,"subject":"Machine Learning"}Чтобы получить обратно объект:
let parsed = JSON.parse(window.localStorage.getItem('result'));
console.log(parsed);Удаление и очистка
window.localStorage.removeItem('Python');
window.localStorage.clear();Длина и перечисление
let len = localStorage.length;
let key = localStorage.key(1);
for (let i = 0; i < localStorage.length; i++) {
let k = localStorage.key(i);
let v = localStorage.getItem(k);
console.log(k, v);
}Простой проект: счётчик, который сохраняется в localStorage
Ниже — минимальный пример страницы и логики на JS. Он демонстрирует работу setItem, getItem и clear в реальном UI.
Создайте index.html и script.js в одной папке.
index.html:
localStorage в JavaScript
localStorage в JavaScript
Score:
Click on the "Increase Score" button to increase the score count
Click on the "Decrease Score" button to decrease the score count
Click on the "Clear localStorage" button to clear the localStorage
You can close the browser tab (or window), and try again.
You'll see that the data still persists and is not lost even after closing
the browser.
script.js:
function increaseCounter() {
var count = Number(window.localStorage.getItem('count'));
count += 1;
window.localStorage.setItem('count', count);
document.getElementById('score').innerHTML = count;
}
function decreaseCounter() {
var count = Number(window.localStorage.getItem('count'));
count -= 1;
window.localStorage.setItem('count', count);
document.getElementById('score').innerHTML = count;
}
function clearCounter() {
window.localStorage.clear();
document.getElementById('score').innerHTML = '';
}
// Инициализация при загрузке: показать текущее значение
window.addEventListener('DOMContentLoaded', function() {
var current = window.localStorage.getItem('count');
if (current === null) {
document.getElementById('score').innerHTML = 0;
} else {
document.getElementById('score').innerHTML = current;
}
});Пояснение: getItem возвращает строку или null. Number(null) даёт 0, поэтому дополнительная обработка для первого нажатия не обязательна. Тем не менее библиотечный код часто проверяет на null или использует явную инициализацию.
Улучшения и практические рекомендации
- Инициализируйте ключи при загрузке. Это даёт предсказуемое поведение.
- Десериализуйте JSON только там, где нужно работать с объектом.
- Обрабатывайте исключения при JSON.parse и при переполнении квоты хранилища.
- Не храните пароли, токены доступа или другие секреты в localStorage.
- Избегайте частых больших записей: localStorage синхронен и может замедлить UI.
Пример: безопасная запись с проверкой
function safeSetItem(key, value) {
try {
window.localStorage.setItem(key, value);
} catch (e) {
// возможные причины: переполнение квоты, режим приватности
console.error('Не удалось записать в localStorage:', e);
}
}Когда localStorage не подходит
Counterexamples — случаи, когда localStorage не должен использоваться:
- Для больших объёмов данных (много мегабайт) — используйте IndexedDB.
- Для чувствительной информации и токенов — используйте безопасное серверное хранение и httpOnly cookies.
- Для данных, требующих конкурентного доступа без блокировки UI — используйте асинхронные хранилища.
- Для данных, которые должны быть доступны между пользователями или устройствами — используйте сервер.
Альтернативы и компромиссы
- Cookies: подходят для отправки данных на сервер вместе с запросами, но ограничены по размеру и медленнее при большом количестве данных.
- IndexedDB: асинхронное, мощное хранилище для больших структур и бинарных данных.
- Cache Storage (Service Workers): кэширование запросов и ресурсов для офлайн-режима.
- Серверное хранение: лучший выбор для чувствительных данных и синхронизации между устройствами.
Ментальные модели и эвристики
- Ментальная модель: localStorage — это ваш локальный «карманный блокнот» в браузере для простых заметок и настроек.
- Эвристика выбора: если данные простые, небольшие и не секретные — localStorage; если сложные, большие или чувствительные — IndexedDB или сервер.
Фактбокс
- Тип: синхронный key—value store
- Формат: строки UTF-16
- Обычно лимит: ~5 МБ
- Доступ: в пределах origin
- Методы: setItem, getItem, removeItem, clear, key, length
Безопасность и соответствие требованиям конфиденциальности
Important: localStorage не шифруется автоматически. Доступ к данным имеют все скрипты с тем же origin. Поэтому:
- Не храните пароли, токены или PII (персональные данные). Для GDPR-совместимости собирайте только необходимую информацию и запрашивайте согласие, если вы сохраняете данные на клиенте для отслеживания пользовательских предпочтений.
- При хранении любых персональных настроек опишите это в политике конфиденциальности и предоставьте пользователю возможность удалить данные.
- Если приложение использует сторонние скрипты, они могут получить доступ к localStorage, поэтому минимизируйте использование внешнего кода или изолируйте функциональность.
Совместимость и миграция
- Поддержка: все современные браузеры поддерживают Web Storage.
- Лимиты могут отличаться по платформам. В приватном режиме некоторые браузеры ограничивают доступ к localStorage или выбрасывают ошибки при попытке записи.
- Миграция в IndexedDB: сериализуйте данные и перемещайте их по шагам с проверкой целостности. При большом объёме делайте миграцию фоново, чтобы не блокировать UI.
Роль-ориентированные чеклисты
Для разработчика:
- Инициализировать ключи при загрузке.
- Использовать try/catch для setItem.
- Не хранить секреты.
- Покрыть функциональность тестами.
Для QA:
- Проверить сохранение после перезагрузки и закрытия вкладки.
- Проверить поведение при отсутствии прав записи (приватный режим).
- Проверить межвкладочную доступность для одного origin.
Для специалистов по безопасности:
- Проанализировать сторонние скрипты на предмет доступа к localStorage.
- Проверить соответствие политике конфиденциальности и требованиям GDPR.
Критерии приёмки
- Данные сохраняются и отображаются после перезагрузки страницы.
- При очистке localStorage весь связанный UI обновляется корректно.
- Записи корректно сериализуются и десериализуются (JSON).
- При переполнении квоты приложение не падает, а корректно обрабатывает ошибку.
Тестовые случаи
- Записать число, перезагрузить страницу, убедиться, что значение восстановлено.
- Записать объект, прочитать и сравнить поля.
- Очистить localStorage и проверить, что все зависимости очищены.
- Смоделировать приватный режим или отключённый localStorage и проверить поведение.
Шаблон миграции в IndexedDB (мини-методология)
- Сериализовать данные из localStorage по блокам.
- Создать хранилище в IndexedDB с нужной структурой.
- Записать блоки в IndexedDB, проверяя целостность.
- Пометить ключи как перенесённые и постепенно удалить из localStorage.
- Убедиться, что функциональность не нарушена.
Примеры кода и сниппеты
Инициализация с запасным значением:
function getNumber(key, fallback = 0) {
const raw = window.localStorage.getItem(key);
return raw === null ? fallback : Number(raw);
}
function setNumber(key, value) {
window.localStorage.setItem(key, String(value));
}Безопасный JSON read:
function safeJSONParse(key) {
try {
const raw = window.localStorage.getItem(key);
return raw ? JSON.parse(raw) : null;
} catch (e) {
console.error('Ошибка парсинга JSON из localStorage', e);
return null;
}
}Короткое резюме
localStorage — удобный инструмент для небольших и не чувствительных данных. Он прост в использовании, но синхронен и ограничен по объёму. Для продвинутых случаев применяйте IndexedDB или серверное хранение. Всегда учитывайте безопасность и требования защиты персональных данных.
Notes: тестируйте поведение в режиме инкогнито и в разных браузерах. Документируйте, какие данные вы храните, и предоставляйте пользователю очевидный способ удаления локальных данных.
Похожие материалы
Отключить Win+L блокировку в Windows
Скачать ISO Windows 11 — 3 простых способа
Как добавить подпись к изображению в PowerPoint
Установка и настройка Nova Launcher на Android