В основе работы с примитивами в localForage лежит абстракция над различными механизмами хранения браузера: IndexedDB, WebSQL и localStorage. Различие между ними напрямую влияет на то, как именно сохраняются строки и числа.
IndexedDB поддерживает хранение значений практически любых типов, включая числа, строки и объекты без предварительной сериализации. WebSQL также оперирует типизированными значениями, но встречается значительно реже. localStorage, напротив, работает исключительно со строками, что требует преобразования любых данных в текстовый формат.
localForage скрывает эти различия, предоставляя единый API, однако внутренние механизмы сериализации и десериализации остаются важной частью поведения при работе с примитивами.
Строки являются наиболее естественным типом для большинства браузерных хранилищ, но их поведение различается в зависимости от драйвера.
В IndexedDB строки сохраняются без изменений, с сохранением Unicode-кодировки. Это означает, что:
localForage при использовании IndexedDB просто передаёт строку как значение ключа или объекта.
При использовании localStorage строка всё равно проходит через слой сериализации localForage. Формально операция выглядит как преобразование:
"текст""\"текст\"" (JSON-строка)При чтении выполняется обратное преобразование через JSON.parse. Это позволяет унифицировать поведение API, но добавляет накладные расходы.
При работе со строками важно учитывать:
"0" не эквивалентна числу 0;"" сохраняется как валидное значение, но
может интерпретироваться как “отсутствие данных” в бизнес-логике
приложения.Числовые значения в JavaScript представлены типом
Number, который соответствует IEEE 754 double precision
floating point. Это накладывает ограничения на точность и диапазон
значений при хранении.
IndexedDB поддерживает числовой тип напрямую, поэтому localForage в этом случае:
Пример логического поведения:
4242 (тип Number сохраняется)В localStorage число проходит через JSON-сериализацию:
42 → "42" → 42 (после
parse)Таким образом, восстановление типа происходит автоматически, но через промежуточное строковое представление.
Особое внимание требуется при работе с нестандартными числовыми значениями.
NaN не равен самому себе и в JSON не имеет прямого
представления. При сериализации:
NaN преобразуется в null при
JSON.stringify;null, а не
NaN.Это приводит к потере семантики значения.
Эти значения также не поддерживаются JSON-форматом. Поведение:
null или строковое
представление в зависимости от окружения;BigInt не поддерживается JSON и не поддерживается localForage напрямую через localStorage-драйвер. Попытка сохранить BigInt приводит к ошибке сериализации или неявному преобразованию в строку.
Ключевой особенностью localForage является унификация API поверх разных систем хранения. Для этого применяется слой сериализации:
Обобщённая схема:
Для чисел и строк это обычно прозрачно, но различия становятся заметны при смене драйвера.
При использовании localForage отсутствует автоматическое приведение типов, характерное для некоторых других систем хранения. Однако косвенные преобразования возникают из-за JSON-сериализации.
Типичные сценарии:
Несмотря на унифицированный API, поведение может различаться в зависимости от окружения.
При смене драйвера возможно изменение типа возвращаемого значения:
IEEE 754 накладывает ограничения:
Некоторые значения не проходят сериализацию:
localForage предназначен для хранения данных, совместимых с JSON и structured clone.
При проектировании структуры данных, где используются строки и числа, важно учитывать:
При работе с наборами значений (например, при использовании
keys() и последующем getItem()):
При миграции между драйверами возможно расхождение в представлении примитивов, особенно при смешанных наборах данных.
Пустые строки и нулевые значения часто приводят к неоднозначной интерпретации:
"" — валидная строка;0 — валидное числовое значение;null — отсутствие значения;undefined — не сохраняется напрямую и может быть
преобразован в null или пропущен.localForage не вводит дополнительной семантики поверх этих значений, оставляя их различие на уровне приложения.
| Тип | IndexedDB | WebSQL | localStorage |
|---|---|---|---|
| String | без изменений | строка | JSON.stringify |
| Number | без изменений | число/строка | JSON.parse |
| NaN | частично поддерживается | нестабильно | преобразуется |
| Infinity | частично поддерживается | нестабильно | теряется |
| BigInt | не поддерживается | не поддерживается | не поддерживается |
localForage обеспечивает единый интерфейс для работы со строками и числами, но фактическое поведение определяется выбранным драйвером хранения. Наиболее предсказуемая модель наблюдается при использовании IndexedDB, где примитивы сохраняются без преобразований. При использовании localStorage вводится дополнительный слой сериализации, влияющий на точность представления и типизацию данных.