Методы minimize и maximize

Intl.Locale представляет собой объект, инкапсулирующий структурированное представление языкового тега BCP 47. В отличие от строкового обозначения локали, например "en-US" или "zh-Hant-TW", экземпляр Intl.Locale позволяет работать с отдельными компонентами локали как с полями объекта: языком, письмом (script), регионом, вариантами и расширениями.

Одной из ключевых возможностей этого объекта являются методы нормализации и расширения локали — maximize() и minimize(). Эти методы опираются на стандарт UTS


Метод maximize()

Метод maximize() используется для расширения локали до максимально полного представления, включающего язык, письмо и регион, если такие данные можно однозначно вывести из базы языковых данных Unicode CLDR.

Поведение метода

При вызове maximize() выполняется процедура добавления так называемых likely subtags (вероятных под-тегов):

  • добавляется скрипт (script), если он отсутствует;
  • добавляется регион (region), если он может быть определён;
  • сохраняется исходная информация, если она уже задана явно.

Сигнатура

locale.maximize()

Метод не мутирует исходный объект, а возвращает новый экземпляр Intl.Locale.

Принцип работы

Если локаль задана неполно, например только языком:

const locale = new Intl.Locale("en");
const maximized = locale.maximize();

результат будет расширен до наиболее вероятного варианта:

console.log(maximized.toString());
// "en-Latn-US"

Здесь:

  • en — язык (английский),
  • Latn — латинское письмо (script),
  • US — наиболее вероятный регион по умолчанию.

Если локаль уже содержит часть информации, метод дополняет только недостающие элементы:

const locale = new Intl.Locale("zh-TW");
const maximized = locale.maximize();

console.log(maximized.toString());
// "zh-Hant-TW"

Здесь:

  • Hant добавляется как письмо (традиционные китайские иероглифы),
  • регион TW остаётся без изменений.

Использование данных CLDR

Механизм maximize() использует таблицы вероятных соответствий:

  • язык → наиболее распространённое письмо
  • язык + письмо → наиболее вероятный регион
  • комбинация языка и региона → уточнение письма при необходимости

Эти данные основаны на статистике использования локалей в реальных системах.


Метод minimize()

Метод minimize() выполняет обратную операцию: удаляет из локали избыточные компоненты, если они могут быть однозначно восстановлены через правила likely subtags.

Поведение метода

Основные задачи:

  • убрать script и region, если они не несут дополнительной информации;
  • оставить минимально достаточную форму локали;
  • сохранить возможность восстановления через maximize().

Сигнатура

locale.minimize()

Метод также возвращает новый экземпляр Intl.Locale, не изменяя исходный объект.


Алгоритм минимизации

Минимизация выполняется в несколько этапов:

  1. Локаль сначала виртуально максимизируется.
  2. Сравнивается с исходной.
  3. Удаляются те части, которые можно восстановить без потери информации.

Пример минимизации полной локали

const locale = new Intl.Locale("en-Latn-US");
const minimized = locale.minimize();

console.log(minimized.toString());
// "en"

Пояснение:

  • en-Latn-US считается избыточным, так как:

    • английский по умолчанию использует латиницу;
    • регион США является наиболее вероятным.
  • в результате остаётся только язык en.


Пример с неоднозначной локалью

const locale = new Intl.Locale("zh-Hant-TW");
const minimized = locale.minimize();

console.log(minimized.toString());
// "zh-Hant-TW"

В данном случае сокращение невозможно, потому что:

  • zh (китайский) имеет несколько письменных систем;
  • Hant (традиционное письмо) важно для различения;
  • регион TW влияет на выбор письменности.

Пример частичной минимизации

const locale = new Intl.Locale("es-ES");
const minimized = locale.minimize();

console.log(minimized.toString());
// "es"

Причина:

  • испанский язык в Испании является дефолтным вариантом;
  • регион не добавляет информации, необходимой для различения вариантов.

Связь minimize и maximize

Оба метода формируют замкнутый цикл нормализации локали:

  • maximize() расширяет локаль до полной формы;
  • minimize() сокращает её до минимально достаточной формы.

Однако результат minimize(maximize(locale)) не всегда идентичен исходной строке, если исходная локаль была избыточно уточнена или, наоборот, содержала нестандартные комбинации.

Пример симметрии

const locale = new Intl.Locale("en-US");

const maximized = locale.maximize();
const minimized = maximized.minimize();

console.log(minimized.toString());
// "en"

Здесь наблюдается нормализация к канонической форме.


Практическое значение методов

Унификация локалей

В системах, где локали приходят из разных источников (браузер, API, пользовательский ввод), они могут иметь различный уровень детализации:

  • "en"
  • "en-US"
  • "en-Latn-US"

Метод minimize() позволяет привести их к единому виду для сравнения и хранения.


Подготовка к локализационным операциям

Многие API Intl используют локали с учётом script и region. maximize() позволяет заранее привести локаль к форме, которая даст более точные результаты форматирования.

Пример:

const locale = new Intl.Locale("sr");
const expanded = locale.maximize();

Результат может различаться:

  • "sr-Cyrl-RS" (кириллица, Сербия)
  • или "sr-Latn-RS" в зависимости от конфигурации и данных CLDR

Сравнение локалей

Минимизация особенно полезна при сравнении:

const a = new Intl.Locale("en-US");
const b = new Intl.Locale("en-GB");

console.log(a.minimize().language === b.minimize().language);
// true

Обе локали сводятся к базовому языку en.


Влияние расширений и Unicode extension tags

Локали могут содержать расширения, например:

const locale = new Intl.Locale("en-US-u-ca-gregory");

Методы maximize() и minimize() не удаляют пользовательские Unicode-расширения (-u-), так как они относятся к настройкам форматирования, а не к базовой структуре языка.


Ограничения и особенности реализации

Зависимость от среды выполнения

Результаты maximize() зависят от:

  • версии ECMAScript реализации;
  • базы CLDR в движке JavaScript;
  • актуальности данных о языковых соответствиях.

Поэтому:

new Intl.Locale("zh").maximize().toString()

может давать разные результаты в разных средах.


Необратимость сокращения в отдельных случаях

Хотя концептуально:

  • maximize расширяет,
  • minimize сокращает,

полная обратимость не гарантируется для всех нестандартных или редких локалей.


Поведение при неизвестных комбинациях

Если локаль содержит нестандартные или нераспознаваемые субтеги:

new Intl.Locale("en-XYZ-AB")

методы могут:

  • игнорировать неизвестные части;
  • либо оставить их без изменений;
  • либо удалить при минимизации, если они не влияют на идентификацию языка.

Структурная роль в Intl API

Intl.Locale является базовым компонентом для других API:

  • Intl.NumberFormat
  • Intl.DateTimeFormat
  • Intl.Collator
  • Intl.RelativeTimeFormat

Передача нормализованной локали позволяет этим API работать предсказуемо, особенно в многоязычных приложениях.


Поведение при цепочечных вызовах

Методы возвращают новые экземпляры, что позволяет строить цепочки:

const locale = new Intl.Locale("fr");

const result = locale.maximize().minimize();

console.log(result.toString());
// "fr"

Цепочка демонстрирует переход через полную форму обратно к минимальной канонической записи.


Итоговая модель трансформации локали

Поведение можно формально представить как преобразования:

  • L — исходная локаль
  • M(L) — maximize
  • m(L) — minimize

Тогда:

  • m(M(L)) → каноническая минимальная форма
  • M(m(L)) → восстановленная вероятная полная форма

Эти операции образуют основу нормализации языковых идентификаторов в JavaScript Intl API.