В Unicode и экосистеме интернационализации письменность (script) рассматривается как отдельный уровень языковой идентификации, независимый от языка и региона. Письменность описывает систему графических символов, используемых для записи текста: латиница, кириллица, арабское письмо, деванагари и другие.
В JavaScript работа с названиями письменностей стандартизирована
через Intl.DisplayNames, где тип данных script
позволяет получать локализованные человекочитаемые названия
письменностей по их ISO-кодам (ISO 15924).
Ключевая особенность модели:
Пример:
Intl API опирается на стандарт ISO 15924, где каждая письменность обозначается четырёхбуквенным кодом:
| Код | Письменность |
|---|---|
| Latn | латиница |
| Cyrl | кириллица |
| Arab | арабское письмо |
| Deva | деванагари |
| Hans | упрощённые китайские иероглифы |
| Hant | традиционные китайские иероглифы |
| Jpan | японское письмо |
| Kore | корейское письмо |
Эти коды используются как входные значения для
Intl.DisplayNames.
scriptОсновной механизм получения названий письменностей реализован через конструктор:
const scriptNames = new Intl.DisplayNames('ru', { type: 'script' });
Первый аргумент задаёт локаль вывода, второй — тип отображаемых данных.
scriptNames.of('Latn'); // "латиница"
scriptNames.of('Cyrl'); // "кириллица"
scriptNames.of('Arab'); // "арабское письмо"
Метод of() принимает код письменности ISO 15924 и
возвращает локализованное название.
Одним из ключевых свойств Intl.DisplayNames является
зависимость результата от локали.
const ru = new Intl.DisplayNames('ru', { type: 'script' });
const en = new Intl.DisplayNames('en', { type: 'script' });
ru.of('Cyrl'); // "кириллица"
en.of('Cyrl'); // "Cyrillic"
Таким образом, один и тот же код может давать разные строковые представления в зависимости от языка интерфейса.
При построении UI для выбора языка часто требуется уточнение письменности:
const dn = new Intl.DisplayNames('ru', { type: 'script' });
const scripts = ['Latn', 'Cyrl', 'Arab'];
const labels = scripts.map(code => ({
code,
label: dn.of(code)
}));
Результат:
[
{ "code": "Latn", "label": "латиница" },
{ "code": "Cyrl", "label": "кириллица" },
{ "code": "Arab", "label": "арабское письмо" }
]
Некоторые языки требуют указания письменности для корректного отображения:
const dn = new Intl.DisplayNames('en', { type: 'script' });
dn.of('Hans'); // "Simplified Han"
dn.of('Hant'); // "Traditional Han"
Это критично для китайского языка, где письменность определяет не только графику, но и частично словарный состав.
Письменность часто используется внутри языковых тегов BCP 47:
zh-Hans → китайский (упрощённая письменность)
zh-Hant → китайский (традиционная письменность)
sr-Cyrl → сербский (кириллица)
sr-Latn → сербский (латиница)
Однако Intl.DisplayNames работает только с кодом
письменности, без полного языкового тега:
const dn = new Intl.DisplayNames('ru', { type: 'script' });
dn.of('Latn'); // корректно
dn.of('sr-Latn'); // некорректно (ожидается только script code)
Если передан неизвестный или неподдерживаемый код, поведение стандартизировано:
const dn = new Intl.DisplayNames('ru', { type: 'script' });
dn.of('XXXX'); // обычно возвращает undefined
Это требует обработки на уровне приложения:
const value = dn.of(code) ?? 'неизвестная письменность';
Создание Intl.DisplayNames — относительно тяжёлая
операция. В производственных приложениях используется кэширование:
const scriptDisplayCache = new Map();
function getScriptDisplay(locale) {
if (!scriptDisplayCache.has(locale)) {
scriptDisplayCache.set(
locale,
new Intl.DisplayNames(locale, { type: 'script' })
);
}
return scriptDisplayCache.get(locale);
}
Использование:
const dn = getScriptDisplay('ru');
dn.of('Cyrl');
Письменности часто используются вместе с языками и регионами для построения сложных интерфейсов локализации.
const dn = new Intl.DisplayNames('ru', { type: 'script' });
const data = [
{ lang: 'sr', script: 'Cyrl' },
{ lang: 'sr', script: 'Latn' }
];
data.map(item => ({
label: `${item.lang} (${dn.of(item.script)})`
}));
Результат:
Поддержка конкретных письменностей зависит от реализации JavaScript-движка и ICU-библиотеки. В разных средах список доступных локализаций может отличаться.
Хотя ISO 15924 содержит большое количество письменностей, браузер может возвращать fallback-значения или исходный код.
Intl.DisplayNames возвращает статическое имя без
грамматических форм:
Письменности часто используются вместе с:
Intl.Locale — для разбора языковых теговIntl.Collator — для сортировки текста в зависимости от
письменностиIntl.Segmenter — для сегментации текста в разных
системах письмаПример комбинирования:
const locale = new Intl.Locale('sr-Cyrl');
const script = locale.script; // "Cyrl"
const dn = new Intl.DisplayNames(locale.toString(), { type: 'script' });
dn.of(script); // "кириллица"
Письменности становятся критичными в системах, где:
Особенно это заметно в:
При работе с письменностями часто требуется нормализация входных данных:
function normalizeScript(code) {
return code.trim().toUpperCase();
}
Однако ISO-коды чувствительны к регистру по соглашению, поэтому нормализация должна быть осторожной:
В реальных системах часто используется массив кодов:
const scripts = ['Latn', 'Cyrl', 'Arab', 'Deva'];
const dn = new Intl.DisplayNames('ru', { type: 'script' });
const result = scripts.reduce((acc, code) => {
acc[code] = dn.of(code);
return acc;
}, {});
Результат:
{
"Latn": "латиница",
"Cyrl": "кириллица",
"Arab": "арабское письмо",
"Deva": "деванагари"
}
Письменность часто становится третьим уровнем локализации:
const locale = new Intl.Locale('zh-Hans-CN');
locale.language; // "zh"
locale.script; // "Hans"
locale.region; // "CN"
В таких структурах Intl.DisplayNames используется для
человекочитаемого отображения каждого уровня независимо.