В Intl-экосистеме JavaScript отсутствующие
локализационные данные не приводят к падению выполнения кода. Вместо
этого применяется многоуровневая система резервирования (fallback),
основанная на стандарте BCP 47, алгоритмах выбора локали и внутренних
таблицах CLDR. Такой подход обеспечивает предсказуемость даже в случаях,
когда запрошенная комбинация языка, региона и опций не поддерживается
полностью.
Каждый конструктор Intl (например,
Intl.NumberFormat, Intl.DateTimeFormat,
Intl.Collator) принимает список предпочтительных локалей.
При этом фактическая локаль выбирается по алгоритму best
fit или lookup, который определяет наиболее
подходящую доступную локаль.
При стратегии lookup система последовательно упрощает
запрос:
ru-KZ-u-ca-gregoryru-KZruen (если русская локаль отсутствует)Каждый шаг удаляет наиболее специфичный компонент до нахождения совпадения.
best fit не обязан строго следовать иерархии BCP 47.
Реализация может:
ru-KZ с ru-RUЭто позволяет движку возвращать более «естественный» результат, даже если точное совпадение отсутствует.
default localeЕсли ни одна из переданных локалей не поддерживается, используется:
en как универсальный fallback в некоторых
реализацияхПример:
const fmt = new Intl.DateTimeFormat(['xx-YY', 'zz-ZZ']);
Если обе локали не существуют, результат будет эквивалентен:
new Intl.DateTimeFormat(Intl.DateTimeFormat().resolvedOptions().locale);
undefined и пустых значенийВ API Intl значение undefined имеет особый
смысл: оно активирует стандартный fallback.
new Intl.NumberFormat(undefined);
Эквивалентно:
new Intl.NumberFormat(defaultLocale);
При этом:
null не используется как валидный fallbackЕсли локаль не содержит данных о форматировании чисел, используется базовая модель:
, или пробел (в зависимости от
дефолта).Пример:
new Intl.NumberFormat('unknown-locale').format(1234567.89);
Результат не ломается, а переключается на системный формат.
Unicode extension nu (numbering system) может быть
проигнорирован:
new Intl.NumberFormat('ar-EG-u-nu-arab').format(123);
Если система счисления arab недоступна:
latnIntl.DateTimeFormat демонстрирует более сложную систему
деградации качества.
Если календарь (ca) не поддерживается:
new Intl.DateTimeFormat('ja-JP-u-ca-japanese');
fallback:
Если указанная таймзона отсутствует:
new Intl.DateTimeFormat('en-US', {
timeZone: 'Unknown/Zone'
});
поведение:
timeZoneЕсли конкретный dateStyle или timeStyle не
поддерживается:
full → long → medium → shortformatToPartsМетод formatToParts сохраняет структуру даже при
деградации локали.
Если локализация частично отсутствует:
Пример:
new Intl.NumberFormat('xx-XX').formatToParts(1000);
Результат может включать:
integergroupdecimalliteralдаже если локаль не определена.
Intl.RelativeTimeFormatОтсутствие поддержки единиц времени приводит к упрощению:
new Intl.RelativeTimeFormat('unknown', { numeric: 'auto' });
fallback:
en-подобной формулировкеНапример:
Intl.PluralRulesЕсли локаль не содержит специальных правил множественного числа:
other как универсальнаяnew Intl.PluralRules('xx-XX').select(1);
результат:
one или other по умолчанию, чаще
otherUnicode extensions позволяют задавать поведение:
ca — календарьnu — система счисленияhc — часовой циклkf — порядок сортировкиЕсли параметр не поддерживается:
Пример:
new Intl.DateTimeFormat('en-US-u-hc-h12');
Если hc не поддерживается → игнорируется, но
форматирование продолжается.
supportedLocalesOfМетод позволяет заранее определить, какие локали реально поддерживаются:
Intl.NumberFormat.supportedLocalesOf(['ru-KZ', 'xx-YY']);
результат:
Это ключевой механизм для предотвращения неожиданных fallback во время форматирования.
resolvedOptions()Каждый Intl-объект может раскрыть фактически применённые
параметры:
const fmt = new Intl.DateTimeFormat(['xx-YY', 'ru']);
fmt.resolvedOptions();
типичные поля:
locale — фактически выбранная локальcalendar — реальный календарьnumberingSystem — активная система счисленияtimeZone — итоговая таймзонаЭто основной инструмент диагностики fallback-цепочек.
Если локаль отсутствует:
new Intl.Collator('unknown').compare('a', 'b');
fallback:
Система Intl работает по принципу постепенного
упрощения:
ru, en, arНекоторые окружения (например, минимальные сборки Node.js или старые браузеры) используют:
В этом случае fallback усиливается:
enFallback в Intl решает три критические задачи:
Стабильность API
Предсказуемость
Грациозная деградация
Intl почти никогда не выбрасывает исключения из-за
локали
Решение принимается во время создания объекта, а не при каждом
format
После резолва fallback больше не пересчитывается
Система fallback в Intl строится вокруг идеи:
Такой подход позволяет API оставаться устойчивым в условиях неполных локализационных данных и различий между окружениями выполнения JavaScript.