Skip to content

6. Символьні рядки

Символьні рядки в JavaScript дуже схожі на рядки в PHP.

Image

6.1. скрипт [str-01]

Перше, що слід зрозуміти, — це те, що після створення рядок більше не можна змінити. Існує безліч методів для створення нового рядка на основі початкового, але сам початковий рядок завжди залишається незмінним. Крім того, символьний рядок може бути двох типів:

  • [string], якщо вона ініціалізована літеровим рядком;
  • [object], якщо вона створена як екземпляр класу [String];

'use strict';

// рядки доступні лише для читання (їх не можна змінювати)

// рядок
const chaîne1 = "abcd ";
// тип
console.log("typeof(chaîne1)=", typeof (chaîne1));
// символ № 2
console.log("chaîne1[2]=", chaîne1[2]);
// викликає помилку
chaîne1[2] = "0";

Виконання


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Temp\19-09-01\javascript\strings\str-01.js"
typeof(chaîne1)= string
chaîne1[2]= c
c:\Temp\19-09-01\javascript\strings\str-01.js:1
TypeError: Cannot assign to read only property '2' of string 'abcd '
at Object.<anonymous> (c:\Temp\19-09-01\javascript\strings\str-01.js:12:12)
at Generator.next (<anonymous>)

6.2. скрипт [str-02]

Цей скрипт демонструє, що рядок можна побудувати двома способами.


'use strict';

// рядки можуть бути двох типів

// літеральний рядок
const chaîne1 = "abcd ";
// тип
console.log("typeof(chaîne1)=", typeof (chaîne1));
// екземпляр класу String
const chaîne2 = new String("xyzt");
// тип
console.log("typeof(chaîne2)=", typeof (chaîne2));
// інший запис (без new) — тип [string], а не [object]
const chaîne3 = String("12 34");
// тип
console.log("typeof(chaîne3)=", typeof (chaîne3));
// тип [string] та тип [object] надають ті самі методи, що й клас String
console.log("chaîne1.length=", chaîne1.length);
console.log("chaîne2.length=", chaîne2.length);

Коментарі

  • рядок 6: звичайний спосіб визначення рядка. [chaîne1] матиме тип [string];
  • рядок 10: рядок можна створити за допомогою конструктора класу [String]. [chaîne2] матиме тип [object];

Виконання


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\strings\str-02.js"
typeof(chaîne1)= string
typeof(chaîne2)= object
typeof(chaîne3)= string
chaîne1.length= 5
chaîne2.length= 4

Тип [string] має доступ до методів класу [String].

6.3. скрипт [str-03]

Цей скрипт демонструє конкретний рядок із інтерполяцією змінних.


'use strict';

// рядок
const chaîne = "Introduction à Javascript par l'exemple";
// рядок з інтерполяцією змінних
const str = `[${chaîne}].substr(3, 2)=` + chaîne.substr(3, 2)
console.log(str);

Коментарі

  • рядок 6: можливі рядки, що містять вирази ${variable}, які замінюються значенням змінної. Тут діє та сама логіка, що й для змінних $ у рядках PHP. Зверніть увагу на запис такого рядка: він оточений «backstick» або зворотним апострофом (AltGr-7 на французькій клавіатурі);

Виконання


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Temp\19-09-01\javascript\strings\tempCodeRunnerFile.js"
[Introduction à Javascript par l'exemple].substr(3, 2)=ro

6.4. скрипт [str-04]

Строка з інтерполяцією змінних залишається недостатньою. Адже неможливо підставити вираз замість змінної у виразі ${variable}. Для тих, хто програмував на C, немає нічого подібного до функцій [printf, sprintf] для написання або побудови форматованих строк. Сотні розробників створили тисячі пакетів JavaScript, що утворюють величезну екосистему. Коли виникає потреба, яку JavaScript не може задовольнити на рівні ядра, настає час шукати пакет, який її задовольнить. Для цього ми використовуємо менеджер пакетів [npm]. Він має опцію [search], яка дозволяє шукати рядок символів в описі пакетів. [npm] повертає список пакетів, що відповідають запиту. Отже, ми будемо шукати рядок [sprintf] в описі пакетів:

Image

  • у стовпці [4] — ключові слова пакетів зі стовпця [3];
  • у стовпці [5] — опис пакетів зі стовпця [3];

Наступним кроком є перехід на сайт інструменту [npm], [https://www.npmjs.com/] та ознайомлення з описом пакетів:

Image

У [3] переглядаємо список пакетів і вибираємо один із них.

Image

В описі пакета міститься інформація щодо його встановлення та використання:

Image

Встановлюємо пакет [sprintf-js] у терміналі [VSCode]:

Image

Ця інсталяція змінить файл [package.json], розташований у кореневій папці [javascript] [2]:

Image

Як бачимо вище, пакет було встановлено в [dependencies], тобто в пакети, необхідні для виконання проєкту. Нагадаємо, що в [devDependencies] розміщуються пакети, необхідні виключно під час розробки проєкту. Вони не використовуються під час виконання. Ця відмінність є важливою, коли потрібно створити остаточну версію проєкту для його запуску в виробництво. Існують інструменти для:

  • об'єднання всіх файлів jS, необхідних для виконання, в один файл. Отже, пакети з [devDependencies] не включаються до цього кінцевого файлу;
  • його мінімізації, тобто зменшення розміру до мінімуму. Для цього, наприклад, видаляються всі коментарі;
  • «зашифрувати» код, щоб його було важко зрозуміти. Наприклад, змінні «taux», «salaire», «impôt» будуть замінені на змінні «a», «b», «c»;
  • здійснити інші оптимізації;

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

Тепер, коли ми маємо пакет [sprintf-js], нам потрібно його використати. Це скрипт [str-04]:


'use strict';
// використання зовнішнього пакета для доступу до функції sprintf
import { sprintf } from 'sprintf-js';
// рядок
const chaîne = "Introduction à Javascript par l'exemple";
// метод
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

У ECMAScript 6 ми використовуємо ключове слово [import] для імпорту об’єкта, експортованого пакетом. Щоб дізнатися, що саме експортує пакет, можна переглянути його код:

Image

  • у [1] — клацнути правою кнопкою миші на імпортованому пакеті;
  • у [2], якщо переглянути його визначення;
  • у [3-4] бачимо, що пакет експортує функцію з назвою [sprintf];

Функція [sprintf] з пакета [sprintf-js] імпортується за допомогою оператора:


import { sprintf } from 'sprintf-js';

Повний код:


'use strict';
// використання зовнішнього пакета для доступу до функції sprintf
import { sprintf } from 'sprintf-js';
// рядок
const chaîne = "Introduction à Javascript par l'exemple";
// метод
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

дає такі результати:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\strings\str-04.js"
c:\Temp\19-09-01\javascript\strings\str-04.js:3
import { sprintf } from 'sprintf-js';
^

SyntaxError: Unexpected token {
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Object.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)

У рядку 3 не розпізнається команда [import]. Це пов’язано з тим, що версія 10.15.1 [node.js], яка використовується в цьому курсі (вересень 2019 р.), ще не відповідає стандарту ECMAScript щодо імпорту пакетів, які називаються модулями. У 2019 році [node.js] відповідає стандарту модулів під назвою CommonJS. Інтеграція модулів ECMAScript у [node.js] запланована на 2020 рік. І тут знову розробники взялися за справу та створили пакети, що дозволяють використовувати модулі ES6 разом із [node.js] вже зараз (2019 рік).

Ми будемо використовувати пакет під назвою [esm] (ECMAScript Modules). Встановлюємо його на терміналі проекту [javascript]:

Image

У [4] ми бачимо, що встановлення пакета [esm] [1-3] змінило файл [javascript/package.json].

На цьому ми ще не закінчили. Щоб модуль [esm] використовувався модулем [node.js], останній потрібно запустити з аргументом [-r esm].

Отже, ми змінюємо конфігурацію розширення [Code Runner] у [VSCode]:

Image

Image

У [11] додаємо аргумент [-r esm] і зберігаємо (Ctrl-S) конфігурацію.

Тепер ми можемо запустити скрипт [str-04]:


'use strict';
// використання зовнішнього пакета для доступу до функції sprintf
import { sprintf } from 'sprintf-js';
// рядок
const chaîne = "Introduction à Javascript par l'exemple";
// метод substr
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

Image

6.5. скрипт [str-05]

Ось що сказано в документації про функцію [sprintf]:

Заповнювачі у форматному рядку позначаються символом % і супроводжуються одним або кількома з таких елементів у наведеному нижче порядку:

  • Необов’язкове число, за яким іде знак $, що визначає, індекс якого аргументу слід використовувати для значення. Якщо це не вказано, аргументи розміщуватимуться в тому самому порядку, що й заповнювачі у вхідному рядку.
  • Необов’язковий знак «+», який змушує ставити перед результатом знак «плюс» або «мінус» для числових значень. За замовчуванням для від’ємних чисел використовується лише знак «-».
  • Необов’язковий специфікатор заповнення, що вказує, який символ використовувати для заповнення (якщо вказано). Можливими значеннями є 0 або будь-який інший символ, перед яким стоїть ' (одинарна лапка). За замовчуванням заповнення здійснюється пробілами.
  • Опціональний знак «-», який змушує sprintf вирівнювати результат цього заповнювача по лівому краю. За замовчуванням результат вирівнюється по правому краю.
  • Необов’язкове число, яке визначає, скільки символів має містити результат. Якщо значення, що повертається, коротше за це число, результат буде доповнено. При використанні з специфікатором типу j (JSON) довжина заповнення визначає розмір табуляції, що використовується для відступу.
  • Необов’язковий модифікатор точності, що складається з символу . (крапка), за яким іде число, яке вказує, скільки цифр слід відображати для чисел з плаваючою комою. При використанні зі специфікатором типу g він визначає кількість значущих цифр. При використанні щодо рядка він призводить до обрізання результату.
  • Специфікатор типу, який може мати один із таких значень:
    • % — повертає літеральний символ %
    • b — повертає ціле число у двійковій системі числення
    • c — повертає ціле число у вигляді символу з відповідним значенням
    • d або i — повертає ціле число у вигляді десяткового числа зі знаком
    • e — повертає число з плаваючою комою у науковій нотації
    • u — повертає ціле число у вигляді десяткового числа без знака
    • f — повертає число типу float без змін; див. примітки щодо точності вище
    • g — повертає число типу float без змін; див. примітки щодо точності вище
    • o — повертає ціле число у вісімковій системі числення
    • s — повертає рядок без змін
    • t — повертає значення true або false
    • T — повертає тип аргументу1
    • v — повертає примітивне значення вказаного аргументу
    • x — повертає ціле число у шістнадцятковій системі числення (малі літери)
    • X — повертає ціле число у вигляді шістнадцяткового числа (великими літерами)
    • j — повертає об’єкт або масив JavaScript у вигляді кодованого рядка JSON

Скрипт [script-05] реалізує деякі з цих форматів:


'use strict';
// використання зовнішнього пакета для доступу до функції sprintf
import { sprintf } from 'sprintf-js';
// рядок
const chaîne = "Javascript";
// рядки символів
console.log(sprintf("[%s, %%s]=>[%s]", chaîne, chaîne));
console.log(sprintf("[%s, %%20s]=>[%20s]", chaîne, chaîne));
console.log(sprintf("[%s, %%-20s]=>[%-20s]", chaîne, chaîne));
// цілі числа
console.log(sprintf("[%d, %%d]=>[%d]", 10, 10));
console.log(sprintf("[%d, %%4d]=>[%4d]", 10, 10));
console.log(sprintf("[%d, %%-4d]=>[%-4d]", 10, 10));
console.log(sprintf("[%d, %%04d]=>[%04d]", 10, 10));
// числа з плаваючою комою
console.log(sprintf("[%f, %%f]=>[%f]", -10.5, -10.5));
console.log(sprintf("[%f, %%10.2f]=>[%10.2f]", -10.5, -10.5));
console.log(sprintf("[%f, %%-10.2f]=>[%-10.2f]", -10.5, -10.5));
console.log(sprintf("[%f, %%010.3f]=>[%010.3f]", -10.5, -10.5));
// json
console.log(sprintf("personne (%%j)=%j", { nom: "mathieu", âge: 34 }));
// тип
console.log(sprintf("type personne (%%T)=%T", { nom: "mathieu", âge: 34 }));
// логічне значення
console.log(sprintf("booléen (%%t)=%t", 4 === 4));

Виконання


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\strings\str-05.js"
[Javascript, %s]=>[Javascript]
[Javascript, %20s]=>[ Javascript]
[Javascript, %-20s]=>[Javascript ]
[10, %d]=>[10]
[10, %4d]=>[ 10]
[10, %-4d]=>[10 ]
[10, %04d]=>[0010]
[-10.5, %f]=>[-10.5]
[-10.5, %10.2f]=>[ -10.50]
[-10.5, %-10.2f]=>[-10.50 ]
[-10.5, %010.3f]=>[-00010.500]
personne (%j)={"nom":"mathieu","âge":34}
type personne (%T)=object
booléen (%t)=true

6.6. скрипт [str-06]

Скрипт [str-06] демонструє деякі методи класу [String], які також можна використовувати для типу [string]:


'use strict';
// використання зовнішнього пакета для доступу до функції sprintf
import { sprintf } from 'sprintf-js';
// рядок
const chaîne = "  Introduction à Javascript ";
// деякі методи
// substr(10,2): 2 символи, починаючи з 10-го
console.log(sprintf("[%s].substr(10,2)=[%s]", chaîne, chaîne.substr(10, 2)));
// trim: видалення пробілів на початку та в кінці рядка (пробіл=\b \t \r \n \f)
console.log(sprintf("[%s].trim()=[%s]", chaîne, chaîne.trim()));
// toLowerCase: перетворення на малі літери
console.log(sprintf("[%s].toLowerCase=[%s]", chaîne, chaîne.toLowerCase()));
// toUpperCase: перетворення на великі літери
console.log(sprintf("[%s].toUpperCase=[%s]", chaîne, chaîne.toUpperCase()));
// indexOf: позиція шуканого підряд ка в рядку, -1, якщо підрядок відсутній
console.log(sprintf("[%s].indexOf('Java')=[%s]", chaîne, chaîne.indexOf('Java')));
console.log(sprintf("[%s].trim().indexOf('abcd')=[%s]", chaîne, chaîne.indexOf('abcd')));
// includes: true, якщо шуканий рядок міститься в рядку
console.log(sprintf("[%s].includes('Java')=[%s]", chaîne, chaîne.includes('Java')));
// length: довжина рядка — це не метод, а властивість
console.log(sprintf("[%s].length=[%s]", chaîne, chaîne.length));
// slice (7,10): підрядок із символів № 7–9
console.log(sprintf("[%s].slice(7,10)=[%s]", chaîne, chaîne.slice(7, 10)));
// match: шукає вираз у рядку — цей вираз може бути регулярним виразом
// /intro/i: регулярний вираз, що позначає рядок [intro] у верхньому або нижньому регістрі
// повертає знайдений рядок
console.log(sprintf("[%s].match(/intro/i)=[%s]", chaîne, chaîne.match(/intro/i)));
// replace: замінює рядок1 на рядок2 у рядку
// замінює перше входження i на x
console.log(sprintf("[%s].replace('i','x')=[%s]", chaîne, chaîne.replace('i', 'x')));
// замінює всі входження i на x
// /i/g — це регулярний вираз, що позначає всі (g) входження i
console.log(sprintf("[%s].replace(/i/g,'x')=[%s]", chaîne, chaîne.replace(/i/g, 'x')));
// split: розділяє рядок на слова, відокремлені параметром split
// повертає масив цих слів
// /\s*/: слова, розділені нулем або кількома пробілами
console.log(sprintf("[%s].split(/\\s*/)=[%s]", chaîne, chaîne.split(/\s*/)));
// /\s+/: слова, розділені одним або кількома пробілами
console.log(sprintf("[%s].split(/\\s+/)=[%s]", chaîne, chaîne.split(/\s+/)));

Виконання


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\strings\str-06.js"
[ Introduction à Javascript ].substr(10,2)=[ti]
[ Introduction à Javascript ].trim()=[Introduction à Javascript]
[ Introduction à Javascript ].toLowerCase=[ introduction à javascript ]
[ Introduction à Javascript ].toUpperCase=[ INTRODUCTION À JAVASCRIPT ]
[ Introduction à Javascript ].indexOf('Java')=[17]
[ Introduction à Javascript ].trim().indexOf('abcd')=[-1]
[ Introduction à Javascript ].includes('Java')=[true]
[ Introduction à Javascript ].length=[28]
[ Introduction à Javascript ].slice(7,10)=[duc]
[ Introduction à Javascript ].match(/intro/i)=[Intro]
[ Introduction à Javascript ].replace('i','x')=[ Introductxon à Javascript ]
[ Introduction à Javascript ].replace(/i/g,'x')=[ Introductxon à Javascrxpt ]
[ Introduction à Javascript ].split(/\s*/)=[,I,n,t,r,o,d,u,c,t,i,o,n,à,J,a,v,a,s,c,r,i,p,t,]
[ Introduction à Javascript ].split(/\s+/)=[,Introduction,à,Javascript,]