Skip to content

Commit

Permalink
update(JS): web/javascript/reference/global_objects/string (#741)
Browse files Browse the repository at this point in the history
* update(JS): web/javascript/reference/global_objects/string

* update(JS): web/javascript/reference/global_objects/string
  • Loading branch information
undead404 authored Sep 23, 2022
1 parent 5ce5fe6 commit 2fff8e6
Showing 1 changed file with 53 additions and 23 deletions.
76 changes: 53 additions & 23 deletions files/uk/web/javascript/reference/global_objects/string/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ const string4 = new String("Об'єкт рядка");
Існує два способи доступитися до окремого символу рядка. Перший — це метод {{jsxref("String.prototype.charAt()", "charAt()")}}:

```js
'cat'.charAt(1); // дає значення "a"
"cat".charAt(1); // дає значення "a"
```

Інший спосіб (який було додано в ECMAScript 5) полягає у розгляді рядка як масивоподібного об'єкта, де кожний символ відповідає певному числовому індексу:

```js
'cat'[1]; // дає значення "a"
"cat"[1]; // дає значення "a"
```

Спроба видалити символ або присвоїти йому значення під час звертання до символу за допомогою квадратних дужок не спрацює. Властивості рядка, до яких в цьому випадку отримує доступ програма, не доступні ні для запису, ні для налаштування. (Докладніше про це на сторінці {{jsxref("Object.defineProperty()")}}.)
Expand All @@ -62,8 +62,8 @@ const string4 = new String("Об'єкт рядка");
У мові «C» для порівняння рядків використовується функція `strcmp()`. У JavaScript для цього існують [оператори більше та менше](/uk/docs/Web/JavaScript/Reference/Operators):

```js
const a = 'a';
const b = 'b';
const a = "a";
const b = "b";
if (a < b) {
// true
console.log(`${a} менше за ${b}`);
Expand All @@ -74,17 +74,35 @@ if (a < b) {
}
```

Подібного результату можна досягнути з методом {{jsxref("String.prototype.localeCompare()", "localeCompare()")}}, який успадковується екземплярами об'єкта `String`.

Зауважте, що `a === b` порівнює рядки `a` і `b` з урахуванням регістру. Якщо потрібно порівняти рядки без урахування регістру літер, використовуйте функцію, подібну до цієї:
Зверніть увагу, що всі оператори порівняння, включно з [`===`](/uk/docs/Web/JavaScript/Reference/Operators/Strict_equality) і [`==`](/uk/docs/Web/JavaScript/Reference/Operators/Equality), порівнюють рядки з урахуванням регістру. Загальноприйнятний спосіб порівнювати рядки без урахування регістру – переводити обидва до одного регістру (вищого чи нижчого) перед їх порівнянням.

```js
function isEqual(str1, str2) {
function areEqualCaseInsensitive(str1, str2) {
return str1.toUpperCase() === str2.toUpperCase();
}
```

У цій функції використано приведення до верхнього регістру замість нижнього, через проблеми з перетворенням певних символів з кодового простору UTF-8.
Вибір того, чи перетворювати з [`toUpperCase()`](/uk/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase), чи з [`toLowerCase()`](/uk/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase), є здебільшого довільним, і жоден з двох варіантів не має цілковитої надійності поза межами латинського алфавіту. Наприклад, і німецьку літеру `ß`, і літери `ss` `toUpperCase()` перетворює на `SS`, тим часом турецька літера `ı` може помилково бути заявлена `toLowerCase()` як нерівна `I`, якщо явно не використати [`toLocaleLowerCase("tr")`](/uk/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase).

```js
const areEqualInUpperCase = (str1, str2) =>
str1.toUpperCase() === str2.toUpperCase();
const areEqualInLowerCase = (str1, str2) =>
str1.toLowerCase() === str2.toLowerCase();
areEqualInUpperCase("ß", "ss"); // true; повинно бути false
areEqualInLowerCase("ı", "I"); // false; повинно бути true
```

Надійне рішення з урахуванням локалі для перевірки нечутливої до регістру рівності – застосовувати API {{jsxref("Intl.Collator")}} чи метод рядка [`localeCompare()`](/uk/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare), – вони поділяють однаковий інтерфейс, – з зі значенням опції [`sensitivity`](/uk/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#sensitivity) `"accent"` чи `"base"`.

```js
const areEqual = (str1, str2, locale = "en-US") =>
str1.localeCompare(str2, locale, { sensitivity: "accent" }) === 0;
areEqual("ß", "ss", "de"); // false
areEqual("ı", "I", "tr"); // true
```

Метод `localeCompare()` дає змогу порівнювати рядки у подібний до `strcmp()` спосіб: дає змогу сортувати рядки з урахуванням локалі.

### Рядки-примітиви і рядки-об'єкти

Expand All @@ -93,7 +111,7 @@ function isEqual(str1, str2) {
Рядкові літерали (виділені одинарними або подвійними лапками), а також рядки, повернуті з викликів `String` без контексту конструктора (тобто викликів, виконаних без ключового слова {{jsxref("Operators/new", "new")}}), є рядками-примітивами. Коли відбувається спроба викликати метод чи звернутися до властивості примітивного рядка, JavaScript автоматично обгортає примітив у виклик конструктора, і вже потім – на об'єкті-обгортці звертається до методу чи властивості.

```js
const strPrim = 'foo'; // Літерал є примітивом рядка
const strPrim = "foo"; // Літерал є примітивом рядка
const strPrim2 = String(1); // Приведено до рядкового примітива "1"
const strPrim3 = String(true); // Приведено до рядкового примітива "true"
const strObj = new String(strPrim); // String із new повертає обгортковий об'єкт рядка
Expand All @@ -109,8 +127,8 @@ console.log(typeof strObj); // Друкує "object"
Рядкові примітиви та об'єкти типу `String` також видають різні результати під час використання {{jsxref("Global_Objects/eval", "eval()")}}. Примітиви, передані до `eval`, вважаються вихідним кодом; натомість об'єкти `String` опрацьовуються як всі інші об'єкти, із поверненням об'єкта в результаті. Наприклад:

```js
const s1 = '2 + 2'; // створює рядковий примітив
const s2 = new String('2 + 2'); // створює об'єкт String
const s1 = "2 + 2"; // створює рядковий примітив
const s2 = new String("2 + 2"); // створює об'єкт String
console.log(eval(s1)); // повертає число 4
console.log(eval(s2)); // повертає рядок "2 + 2"
```
Expand Down Expand Up @@ -172,9 +190,9 @@ console.log(eval(s2.valueOf())); // повертає число 4

```js
const longString =
'Це — дуже довга стрічка тексту, яку потрібно ' +
'розбити на декілька окремих рядків, бо ' +
'інакше цей код буде важко читати.';
"Це — дуже довга стрічка тексту, яку потрібно " +
"розбити на декілька окремих рядків, бо " +
"інакше цей код буде важко читати.";
```

Або ж можна використати обернену скісну риску (`\`) в кінці кожного рядка, щоб позначити, що стрічка продовжується на наступному рядку. Обов'язково слід впевнитись, що після скосу немає пробілу чи якихось інших символів (окрім перенесення на новий рядок), або відступів, інакше такий запис працювати не буде.
Expand All @@ -183,9 +201,9 @@ const longString =

```js
let longString =
'Це — дуже довга стрічка тексту, яку потрібно \
"Це — дуже довга стрічка тексту, яку потрібно \
розбити на декілька окремих рядків, бо \
інакше це код буде важко читати.';
інакше це код буде важко читати.";
```

Обидва методи дадуть в результаті ідентичні рядки.
Expand All @@ -201,16 +219,16 @@ let longString =
Слід бути обережними з рівнями символів, на котрих відбувається обхід. Наприклад, [`split("")`](/uk/docs/Web/JavaScript/Reference/Global_Objects/String/split) розіб'є на кодові одиниці UTF-16 і розділить сурогатні пари. Рядкові індекси також вказують на індекси всіх кодових одиниць UTF-16. З іншого боку, [`@@iterator()`](/uk/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator) виконує обхід за кодовими точками Юнікоду. Обхід за графемними кластерами потребуватиме написання певного коду самотужки.

```js
'😄'.split(''); // ['\ud83d', '\ude04']; розбиває на два самотні сурогати
"😄".split(""); // ['\ud83d', '\ude04']; розбиває на два самотні сурогати
// "Рука тильним боком, вказівний направо: темний тон шкіри"
[...'👉🏿']; // ['👉', '🏿']
[..."👉🏿"]; // ['👉', '🏿']
// розбиває на базовий емоджі "Рука тильним боком, вказівний направо" і
// емоджі "Темний тон шкіри"
// "Родина: Чоловік, Хлопчик"
[...'👨‍👦']; // [ '👨', '‍', '👦' ]
[..."👨‍👦"]; // [ '👨', '‍', '👦' ]
// розбиває на емоджі "Чоловік" та емоджі "Хлопчик", сполучені з'єднувачем нульової ширини
// Прапор ООН
[...'🇺🇳']; // [ '🇺', '🇳' ]
[..."🇺🇳"]; // [ '🇺', '🇳' ]
// розбиває на дві літери – "індикатори регіону": "U" та "N".
// Всі емоджі-прапори утворені сполученням двох літер – індикаторів регіону
```
Expand Down Expand Up @@ -314,9 +332,9 @@ let longString =

## Методи для обгортання в HTML

> **Застереження:** Застарілі. Уникайте вживання цих методів.
> **Застереження:** Нерекомендовані. Уникайте вживання цих методів.
>
> Вони мають обмежене застосування, оскільки надають лише підмножину наявних HTML-тегів та атрибутів.
> Вони мають обмежене застосування, оскільки засновані на дуже старому стандарті HTML і надають лише підмножину наразі доступних тегів та атрибутів HTML. Чимало з них нині створює нерекомендовану чи нестандартну розмітку. На додачу до цього, ці методи виконують просте склеювання рядків, без жодних валідації й очищення, що робить їх потенційною загрозою безпеці, коли безпосередньо вставляти їх результат за допомогою [`innerHTML`](/uk/docs/Web/API/Element/innerHTML). Натомість слід використовувати [DOM API](/uk/docs/Web/API/Document_Object_Model), як то [`document.createElement()`](/uk/docs/Web/API/Document/createElement).
- {{jsxref("String.prototype.anchor()")}} (якір) {{Deprecated_Inline}}
- : {{htmlattrxref("name", "a", "&lt;a name=\"name\"&gt;")}} (ціль для гіперпосилань)
Expand Down Expand Up @@ -345,6 +363,18 @@ let longString =
- {{jsxref("String.prototype.sup()")}} (надрядковий) {{Deprecated_Inline}}
- : {{HTMLElement("sup")}}

Зверніть увагу, що ці методи не перевіряють, чи містить сам рядок теги HTML, тож можливо створити недійсний HTML:

```js
"</b>".bold(); // <b></b></b>
```

Єдине екранування, котре вони виконують – заміна `"` в значеннях атрибутів на `&quot;` (це стосується {{jsxref("String/anchor", "anchor()")}}, {{jsxref("String/fontcolor", "fontcolor()")}}, {{jsxref("String/fontsize", "fontsize()")}} і {{jsxref("String/link", "link()")}})

```js
"foo".anchor('"Hello"'); // <a name="&quot;Hello&quot;">foo</a>
```

## Приклади

### Перетворення рядків
Expand Down

0 comments on commit 2fff8e6

Please sign in to comment.