String.prototype.normalize()

Метод normalize() (нормалізувати, привести до норми) значень повертає нормалізовану форму Unicode свого рядка.

Спробуйте його в дії

Синтаксис

normalize()
normalize(form)

Параметри

form Необов'язкове

Форма нормалізації Unicode, задана одним із чотирьох значень: "NFC", "NFD", "NFKC" чи "NFKD". Якщо цей параметр не задано, або передано undefined, буде використана "NFC".

Ці варіанти мають наступні значення:

"NFC"

Канонічна декомпозиція з наступною Канонічною композицією.

"NFD"

Канонічна декомпозиція.

"NFKC"

Сумісна декомпозиція з наступною Канонічною композицією.

"NFKD"

Сумісна декомпозиція.

Повернене значення

Рядок, що містить нормалізовану форму Unicode переданого рядка.

Винятки

RangeError

Викидається, якщо аргумент form містить значення, відмінне від вказаних вище.

Опис

Кожному окремому символу Unicode призначає числове значення, назване кодовою точкою. Наприклад, для літери "A" визначено кодову точку U+0041. Утім, інколи один і той самий абстрактний символ можна позначати декількома різними кодовими точками, або навіть їх послідовністю. Наприклад, символ "ñ" можна позначити одним із двох способів:

  • Єдина кодова точка U+00F1.
  • Кодова точка літери "n" (U+006E), із кодовою точкою комбінованої тильди (U+0303) одразу за нею.
const string1 = "\u00F1";
const string2 = "\u006E\u0303";

console.log(string1); // ñ
console.log(string2); // ñ

Щоправда, оскільки це різні кодові точки, під час порівняння такі рядки не будуть вважатися однаковими. Більш того, кількість кодових точок теж відрізняється, тому довжини цих рядків також різні.

const string1 = "\u00F1"; // ñ
const string2 = "\u006E\u0303"; // ñ

console.log(string1 === string2); // false
console.log(string1.length); // 1
console.log(string2.length); // 2

Метод normalize() допомагає розв'язати цю проблему шляхом перетворення рядка на нормалізовану форму, спільну для всіх послідовностей кодових точок, яким відповідають однакові символи. Існує дві основні форми нормалізації: одна заснована на канонічній еквівалентності, а інша — на сумісності.

Нормалізація через канонічну еквівалентність

В Unicode дві послідовності кодових точок канонічно еквівалентні, якщо вони позначають ті самі абстрактні символи. Вони повинні завжди мати однаковий візуальний вигляд і поведінку (наприклад, вони повинні завжди однаково сортуватись).

Для отримання форми рядка, яка буде однаковою для всіх канонічно еквівалентних рядків, метод normalize() вживається з аргументом "NFD" чи "NFC". У наведеному нижче прикладі відбувається нормалізація двох різних варіацій символу "ñ":

let string1 = "\u00F1"; // ñ
let string2 = "\u006E\u0303"; // ñ

string1 = string1.normalize("NFD");
string2 = string2.normalize("NFD");

console.log(string1 === string2); // true
console.log(string1.length); // 2
console.log(string2.length); // 2

Компонована те декомпонована форми

Варто зауважити, що довжина форми, нормалізованої методом "NFD", дорівнює 2. Так виходить, тому що "NFD" видає декомпоновану версію канонічної форми, в якій поодинокі кодові точки розділені на декілька базових. Декомпонована канонічна форма літери "ñ" — це послідовність "\u006E\u0303".

Для отримання компонованої канонічної форми, в якій декілька послідовних кодових точок заміняються їх одинарними відповідниками (де це можливо), слід передати аргумент "NFC". Компонована канонічна форма літери "ñ" — це "\u00F1":

let string1 = "\u00F1"; // ñ
let string2 = "\u006E\u0303"; // ñ

string1 = string1.normalize("NFC");
string2 = string2.normalize("NFC");

console.log(string1 === string2); // true
console.log(string1.length); // 1
console.log(string2.length); // 1
console.log(string2.codePointAt(0).toString(16)); // f1

Сумісна нормалізація

В Unicode дві послідовності кодових точок — сумісні, якщо вони позначають однакові абстрактні символи. Сумісні форми повинні однаково оброблятись у деяких (проте не обов'язково у всіх) застосунках.

Всі канонічно еквівалентні форми також є сумісними, але не навпаки.

Наприклад:

  • кодова точка U+FB00 позначає лігатуру "ff". Вона сумісна з двома послідовними кодовими точками U+0066 ("ff").
  • кодова точка U+24B9 позначає символ "Ⓓ". Вона сумісна з кодовою точкою U+0044 ("D").

В одних контекстах (зокрема сортування) їх слід вважати еквівалентними, в інших (таких, як зовнішній вигляд) — ні, тому вони не є канонічно еквівалентними.

Для отримання форми рядка, яка буде однаковою для всіх сумісних рядків, використовується normalize() з аргументом "NFKD" чи "NFKC":

let string1 = "\uFB00";
let string2 = "\u0066\u0066";

console.log(string1); // ff
console.log(string2); // ff
console.log(string1 === string2); // false
console.log(string1.length); // 1
console.log(string2.length); // 2

string1 = string1.normalize("NFKD");
string2 = string2.normalize("NFKD");

console.log(string1); // ff <- вигляд змінився
console.log(string2); // ff
console.log(string1 === string2); // true
console.log(string1.length); // 2
console.log(string2.length); // 2

Під час застосування сумісної нормалізації важливо врахувати, для чого ті рядки будуть потім використовуватись, оскільки така нормалізована форма підходить не для всіх застосувань. В наведеному вище прикладі нормалізація чудово підходить для пошуку, оскільки вона дає змогу користувачу знайти рядок шляхом пошуку літери "f". Проте вона може не підходити для зображення, оскільки візуально вигляд нормалізованої форми відрізняється.

Як і з канонічною нормалізацією, можна отримати компоновану чи декомпоновану сумісні форми шляхом передачі аргументів "NFKD" чи "NFKC", відповідно.

Приклади

Застосування normalize()

// Початковий рядок

// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
// U+0323: COMBINING DOT BELOW
const str = "\u1E9B\u0323";

// Канонічна компонована форма (NFC)

// U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
// U+0323: COMBINING DOT BELOW
str.normalize("NFC"); // '\u1E9B\u0323'
str.normalize(); // те саме, що й вище

// Канонічна декомпонована форма (NFD)

// U+017F: LATIN SMALL LETTER LONG S
// U+0323: COMBINING DOT BELOW
// U+0307: COMBINING DOT ABOVE
str.normalize("NFD"); // '\u017F\u0323\u0307'

// Сумісна компонована форма (NFKC)

// U+1E69: LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
str.normalize("NFKC"); // '\u1E69'

// Сумісна декомпонована форма (NFKD)

// U+0073: LATIN SMALL LETTER S
// U+0323: COMBINING DOT BELOW
// U+0307: COMBINING DOT ABOVE
str.normalize("NFKD"); // '\u0073\u0323\u0307'

Специфікації

Сумісність із браузерами

desktop mobile server
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet Deno Node.js
normalize
Chrome Full support 34
Edge Full support 12
Firefox Full support 31
Internet Explorer No support No
Opera Full support 21
Safari Full support 10
WebView Android No support No
Chrome Android Full support 34
Firefox for Android Full support 31
Opera Android Full support 21
Safari on iOS Full support 10
Samsung Internet Full support 2.0
Deno Full support 1.0
Node.js Full support 0.12.0

Дивіться також