From cbfdf1d8932340da66845dafb0cf49ac2283cc75 Mon Sep 17 00:00:00 2001 From: Vitalii Perehonchuk Date: Wed, 14 Feb 2024 14:03:27 +0200 Subject: [PATCH 1/3] update(JS): web/javascript/reference/global_objects/string/length --- .../reference/global_objects/string/length/index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/files/uk/web/javascript/reference/global_objects/string/length/index.md b/files/uk/web/javascript/reference/global_objects/string/length/index.md index d3fb47f60a..2960173b07 100644 --- a/files/uk/web/javascript/reference/global_objects/string/length/index.md +++ b/files/uk/web/javascript/reference/global_objects/string/length/index.md @@ -27,6 +27,16 @@ browser-compat: javascript.builtins.String.length - У Firefox найбільша можлива довжина – 230 - 2 (\~2GiB). До Firefox 65 ця межа дорівнювала 228 - 1 (\~512MiB). - У Safari найбільша можлива довжина – 231 - 1 (\~4GiB). +При роботі з великими рядками в інших кодуваннях (наприклад, файлами або згустками у кодуванні UTF-8) слід пам'ятати, що при завантаженні даних у рядок JS кодуванням завжди стає UTF-16. Розмір рядка може відрізнятися від розміру вихідного файлу. + +```js +const str1 = "a".repeat(2 ** 29 - 24); // Успіх +const str2 = "a".repeat(2 ** 29 - 23); // RangeError: Invalid string length + +const buffer = new Uint8Array(2 ** 29 - 24).fill("a".codePointAt(0)); // Цей буфер має розмір 512МіБ +const str = new TextDecoder().decode(buffer); // Цей рядок має розмір 1ГіБ +``` + В порожнього рядка довжина `length` дорівнює 0. Статична властивість `String.length` не має жодного відношення до довжин рядків. Це [арність](/uk/docs/Web/JavaScript/Reference/Global_Objects/Function/length) функції `String` (в широкому розумінні — число формальних аргументів функції), яка дорівнює 1. From fe0a005425d8d126e5e882891a645984f0282229 Mon Sep 17 00:00:00 2001 From: Vitalii Perehonchuk Date: Wed, 14 Feb 2024 14:23:34 +0200 Subject: [PATCH 2/3] update(JS): web/javascript/reference/global_objects/string/length --- .../reference/global_objects/string/length/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/uk/web/javascript/reference/global_objects/string/length/index.md b/files/uk/web/javascript/reference/global_objects/string/length/index.md index 2960173b07..4b1128f228 100644 --- a/files/uk/web/javascript/reference/global_objects/string/length/index.md +++ b/files/uk/web/javascript/reference/global_objects/string/length/index.md @@ -21,9 +21,9 @@ browser-compat: javascript.builtins.String.length Ця властивість повертає число кодових одиниць у рядку. JavaScript використовує кодування [UTF-16](/uk/docs/Web/JavaScript/Reference/Global_Objects/String#symvoly-utf-16-kodovi-tochky-unicode-ta-hrafemni-klastery), згідно з яким кожен символ Unicode може бути закодований у вигляді однієї або двох кодових одиниць, тож може статись таке, що значення, повернене `length`, не збігатиметься з фактичним числом символів Unicode у ряду. Для поширених систем письма штибу латиниці, кирилиці, загальновідомих китайських, японських і корейських символів тощо це не повинно бути проблемою, але при роботі з певними писемностями, як то емоджі, [математичними символами](https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols) або маловідомими китайськими символами, може знадобитись враховування різниці між кодовими одиницями та символами. -Специфікація мови вимагає, аби рядки мали найбільшу можливу довжину 253 - 1 елементів, що дорівнює верхній межі [точних цілих чисел](/uk/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER). Проте рядок з такою довжиною потребує 16384 ТіБ місця, а це не вміститься в жодну доцільну пам'ять пристрою, тож реалізації мають тенденцію до заниження цього порогу, так, щоб довжину рядка можна було зручно зберігати як 32-бітне ціле число. +Специфікація мови вимагає, аби рядки мали найбільшу можливу довжину 253 - 1 елементів, що дорівнює верхній межі [точних цілих чисел](/uk/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER). Проте рядок з такою довжиною потребує 16384 ТіБ місця, а це не вміститься в жодну доцільну пам'ять пристрою, тож реалізації мають тенденцію до заниження цього порогу, так, щоб довжину рядка можна було зручно зберігати як 32-бітове ціле число. -- У V8 (що використовується в Chrome і Node) найбільша можлива довжина – 229 - 24 (\~1GiB). На 32-бітних системах найбільша можлива довжина – 228 - 16 (\~512MiB). +- У V8 (що використовується в Chrome і Node) найбільша можлива довжина – 229 - 24 (\~1GiB). На 32-бітових системах найбільша можлива довжина – 228 - 16 (\~512MiB). - У Firefox найбільша можлива довжина – 230 - 2 (\~2GiB). До Firefox 65 ця межа дорівнювала 228 - 1 (\~512MiB). - У Safari найбільша можлива довжина – 231 - 1 (\~4GiB). From 43d7bec831326d9be10cf5569361635fa2d09939 Mon Sep 17 00:00:00 2001 From: Vitalii Perehonchuk Date: Sat, 13 Apr 2024 21:12:15 +0300 Subject: [PATCH 3/3] update(JS): web/javascript/reference/global_objects/string/length --- .../reference/global_objects/string/length/index.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/files/uk/web/javascript/reference/global_objects/string/length/index.md b/files/uk/web/javascript/reference/global_objects/string/length/index.md index 4b1128f228..9816b5eb9d 100644 --- a/files/uk/web/javascript/reference/global_objects/string/length/index.md +++ b/files/uk/web/javascript/reference/global_objects/string/length/index.md @@ -53,6 +53,19 @@ function getCharacterLength(str) { console.log(getCharacterLength("А\uD87E\uDC04Я")); // 3 ``` +За потреби порахувати символи за _графемними кластерами_ скористайтесь [`Intl.Segmenter`](/uk/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter). Можна спершу передати рядок, який необхідно розбити, до методу [`segment()`](/uk/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/segment), а тоді ітерувати по поверненому об'єкту `Segments`, щоб отримати довжину: + +```js +function getGraphemeCount(str) { + const segmenter = new Intl.Segmenter("en-US", { granularity: "grapheme" }); + // Об'єкт-ітератор Segments, який вжито тут, ітерує по символах у вигляді графемних кластерів, + // кожен з яких може складатися з кількох символів Unicode + return [...segmenter.segment(str)].length; +} + +console.log(getGraphemeCount("👨‍👩‍👧‍👧")); // 1 +``` + ## Приклади ### Базове застосування