Международное API в JavaScript построено вокруг строгого принципа: поведение должно оставаться предсказуемым при изменении версий движков и окружений. Это достигается сочетанием спецификации ECMAScript Internationalization API и зависимостью от ICU (International Components for Unicode), которая поставляет локализационные данные.
Обратная совместимость в этом контексте не означает неизменность функциональности, а означает стабильность контрактов: одинаковые входные данные должны давать максимально близкие результаты при разных версиях среды выполнения.
Intl API не является полностью самодостаточным слоем JavaScript-движка. Основная логика форматирования делегируется ICU.
ICU определяет:
Из этого следует ключевой аспект обратной совместимости: различие версий ICU может менять результат форматирования без изменения JavaScript-кода.
Пример:
Это приводит к ситуации, когда один и тот же код:
new Intl.DateTimeFormat("ru-RU", { dateStyle: "full" }).format(new Date())
может возвращать слегка отличающиеся строки в разных окружениях.
ECMAScript Internationalization API фиксирует:
Стабильность обеспечивается тем, что изменения добавляются только через расширение возможностей, но не через изменение существующего поведения.
Например:
Intl.DateTimeFormat не меняет порядок компонентов даты
задним числомIntl.NumberFormat сохраняет форматирование группировок
цифр для заданной локалиОдним из ключевых механизмов совместимости является алгоритм выбора локали.
При запросе:
new Intl.NumberFormat("ru-KZ")
движок выполняет цепочку:
ru-KZruen или дефолт ICUЭтот механизм гарантирует, что код не падает при отсутствии локали, а деградирует предсказуемо.
Поскольку Intl расширяется поэтапно, каждая новая сущность требует проверки доступности.
if (typeof Intl.RelativeTimeFormat !== "undefined") {
// безопасное использование
}
Некоторые методы появляются позже:
formatToPartsformatRangeresolvedOptionsПример проверки:
if (typeof Intl.DateTimeFormat.prototype.formatToParts === "function") {
// структурированное форматирование доступно
}
Развитие Intl происходит неравномерно между средами:
| Возможность | Старые среды | Современные среды |
|---|---|---|
| Intl.PluralRules | отсутствует | доступен |
| Intl.RelativeTimeFormat | отсутствует | доступен |
| Intl.Segmenter | отсутствует | частичная поддержка |
Для обеспечения совместимости используются полифиллы, которые имитируют недостающие части API.
Например, Intl.PluralRules может быть эмулирован:
Используются специализированные пакеты:
В некоторых сборках среды ICU урезан.
Даже при стабильности API возможны изменения в результате форматирования.
Причины:
Пример изменения:
Это считается допустимым видом эволюции API.
Intl.Locale добавляет структурированное представление
локали.
const loc = new Intl.Locale("ru-KZ-u-nu-latn");
Проблема совместимости:
Intl.LocaleFallback поведение:
Intl API спроектирован так, чтобы игнорировать неизвестные параметры вместо выброса ошибок.
Пример:
new Intl.DateTimeFormat("ru", {
dateStyle: "full",
unknownOption: true
});
Поведение:
unknownOption игнорируетсяЭто критический элемент обратной совместимости: новые версии API не ломают старый код с дополнительными опциями.
Вместо явного versioning используется проверка возможностей.
Intl.NumberFormat.supportedLocalesOf(["ru", "en"]);
Возвращает список реально поддерживаемых локалей, позволяя избежать ручных проверок.
new Intl.NumberFormat("ru").resolvedOptions();
Позволяет понять, какие настройки фактически применились после fallback.
formatRange появился позже классических методов.
new Intl.DateTimeFormat("ru").formatRange(date1, date2);
Проблема совместимости:
format()Fallback стратегия:
Intl.NumberFormat считается наиболее стабильной частью
API.
Гарантируется:
Однако:
Intl.Collator зависит от сложных правил сортировки.
new Intl.Collator("ru").compare("ё", "е");
Проблема:
Расширение Intl происходит по принципу:
Добавление новых API:
Intl.RelativeTimeFormatIntl.PluralRulesIntl.SegmenterIntl.DisplayNamesКаждый новый модуль полностью изолирован от старых.
Ключевая модель поведения Intl:
Примеры деградации:
Система обратной совместимости Intl строится на трёх слоях:
Эта модель позволяет API оставаться расширяемым без разрушения существующих приложений, при этом допуская эволюцию языковых и региональных стандартов без изменения интерфейсов JavaScript-кода.