Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update(JS): web/javascript/reference/global_objects/string/length #2802

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,22 @@ 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) або маловідомими китайськими символами, може знадобитись враховування різниці між кодовими одиницями та символами.

Специфікація мови вимагає, аби рядки мали найбільшу можливу довжину 2<sup>53</sup> - 1 елементів, що дорівнює верхній межі [точних цілих чисел](/uk/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER). Проте рядок з такою довжиною потребує 16384 ТіБ місця, а це не вміститься в жодну доцільну пам'ять пристрою, тож реалізації мають тенденцію до заниження цього порогу, так, щоб довжину рядка можна було зручно зберігати як 32-бітне ціле число.
Специфікація мови вимагає, аби рядки мали найбільшу можливу довжину 2<sup>53</sup> - 1 елементів, що дорівнює верхній межі [точних цілих чисел](/uk/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER). Проте рядок з такою довжиною потребує 16384 ТіБ місця, а це не вміститься в жодну доцільну пам'ять пристрою, тож реалізації мають тенденцію до заниження цього порогу, так, щоб довжину рядка можна було зручно зберігати як 32-бітове ціле число.

- У V8 (що використовується в Chrome і Node) найбільша можлива довжина – 2<sup>29</sup> - 24 (\~1GiB). На 32-бітних системах найбільша можлива довжина – 2<sup>28</sup> - 16 (\~512MiB).
- У V8 (що використовується в Chrome і Node) найбільша можлива довжина – 2<sup>29</sup> - 24 (\~1GiB). На 32-бітових системах найбільша можлива довжина – 2<sup>28</sup> - 16 (\~512MiB).
- У Firefox найбільша можлива довжина – 2<sup>30</sup> - 2 (\~2GiB). До Firefox 65 ця межа дорівнювала 2<sup>28</sup> - 1 (\~512MiB).
- У Safari найбільша можлива довжина – 2<sup>31</sup> - 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.
Expand All @@ -43,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
```

## Приклади

### Базове застосування
Expand Down
Loading