У JavaScript текстові дані зберігаються у вигляді рядків. Не існує окремого типу для одного символу.
Внутрішній формат для рядків завжди UTF-16, він не привʼязаний до кодування сторінки.
Лапки
Згадаймо види лапок.
Рядки можуть бути включені в одинарні лапки, подвійні лапки або зворотні знаки:
let single = 'одинарні-лапки';
let double = "подвійні-лапки";
let backticks = `зворотні-лапки`;
Одинарні та подвійні лапки по суті однакові. Однак зворотні лапки дозволяють нам вставляти будь-який вираз у рядок, загортаючи його у ${…}
:
function sum(a, b) {
return a + b;
}
alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.
Ще однією перевагою використання зворотних лапок є те, що вони дозволяють рядку охоплювати кілька ліній:
let guestList = `Гості:
* Іван
* Петро
* Марія
`;
alert(guestList); // список гостей в кілька рядків
Виглядає природно, правда? Але одинарні або подвійні лапки так не працюють.
Якщо ми спробуємо їх використати в кілька рядків, буде помилка:
let guestList = "Гості: // Помилка: Unexpected token ILLEGAL
* Іван";
Одинарні та подвійні лапки беруть свій початок з давніх часів створення мови, коли не було потреби у багатолінійних рядках. Зворотні лапки зʼявилися набагато пізніше і тому є більш універсальними.
Зворотні лапки також дозволяють нам задати “шаблонну функцію” перед першими зворотніми лапками. Синтаксис такий: func`string`
. Функція func
викликається автоматично, отримує рядок і вбудовані в неї вирази і може їх обробити. Це називається “теговим шаблоном”. Ця функція полегшує реалізацію користувацької шаблонізації, але рідко використовується на практиці. Детальніше про це можна прочитати в посібнику.
Спеціальні символи
Ще можна створити багатолінійні рядки з одинарними та подвійними лапками за допомогою так званого “символу нового рядка”, записаного як \n
, який позначає розрив рядка:
let guestList = "Гості:\n * Іван\n * Петро\n * Марія";
alert(guestList); // список гостей в декілька рядків
Наприклад, ці два рядки рівнозначні, просто написані по-різному:
let str1 = "Привіт\nСвіт"; // два рядки з використанням "символу нового рядка"
// два рядки з використанням звичайного нового рядка та зворотних лапок
let str2 = `Привіт
Світ`;
alert(str1 == str2); // true
Є й інші, менш поширені “спеціальні” символи.
Ось повний список:
Символ | Опис |
---|---|
\n |
Розрив рядка |
\r |
У текстових файлах Windows комбінація двох символів \r\n являє собою розрив рядка, тоді як в інших ОС, це просто \n . Так склалось з історичних причин, більшість ПЗ під Windows також розуміє \n |
\' , \" |
Лапки |
\\ |
Зворотний слеш |
\t |
Знак табуляції |
\b , \f , \v |
Backspace, Form Feed, Vertical Tab – зберігаються для зворотної сумісності, зараз не використовуються |
\xXX |
Символ з шістнадцятковим юнікодним кодом '\x7A' – це те ж саме що і 'z' |
\uXXXX |
Символ з шістнадцятковим юнікодним кодом XXXX в кодуванні UTF-16, наприклад \u00A9 – це юнікодний символ для знаку копірайту © . Шістнадцятковий код обовʼязково має складатись з 4 символів |
\u{X…XXXXXX} (від 1 до 6 шістнадцяткових символів) |
Юнікодний символ в кодуванні UTF-32. Деякі рідкісні символи кодуються двома юнікодними символами, що займають 4 байти. Таким чином ми можемо вставляти довгі коди |
Приклади з Юнікодом:
alert( "\u00A9" ); // ©
alert( "\u{20331}" ); // 佫, рідкісний китайський ієрогліф (довгий юнікод)
alert( "\u{1F60D}" ); // 😍, емодзі посмішки з очима в формі сердець (інший довгий юнікод)
Усі спеціальні символи починаються зі зворотного слеша \
. Його також називають “символом екранування”.
Ми також можемо його використати, якщо хочемо вставити лапки в рядок.
Наприклад:
alert( 'Ім\'я моє — Морж!' ); // Ім'я моє — Морж!
Як бачите, ми повинні “екранувати” лапку зворотним слешем \'
, оскільки інакше це означало б кінець рядка.
Звісно, потрібно “екранувати” лише такі лапки, якими обрамлений рядок. Як елегантніше рішення, ми могли б замість цього скористатися подвійними або зворотними лапками:
alert( `Ім'я моє — Морж!` ); // Ім'я моє — Морж!
Зверніть увагу, що зворотний слеш \
в JavaScript служить для правильного зчитування рядка. Рядок в памʼяті не містить \
. Ви можете чітко це побачити у alert
з наведених вище прикладів.
Але що, якщо нам потрібно показати зворотний слеш \
всередині рядка?
Це можна зробити додаванням ще одного зворотного слеша \\
:
alert( `Зворотний слеш: \\` ); // Зворотний слеш: \
Довжина рядка
Властивість length
містить в собі довжину рядка:
alert( `Моє\n`.length ); // 4
Зверніть увагу, що \n
– це один спеціальний символ, тому довжина рівна 4
.
length
– це властивістьЛюди з досвідом роботи в інших мовах випадково намагаються викликати властивість, додаючи круглі дужки: вони пишуть str.length()
замість str.length
. Це не спрацює.
Зверніть увагу, що str.length
– це числове значення, а не функція, додавати дужки не потрібно.
Доступ до символів
Отримати символ, котрий займає позицію pos
, можна за допомогою квадратних дужок: [pos]
, або викликати метод str.charAt(pos). Перший символ займає нульову позицію.
let str = `Привіт`;
// перший символ
alert( str[0] ); // П
alert( str.charAt(0) ); // П
// останній символ
alert( str[str.length - 1] ); // т
Квадратні дужки – це сучасний спосіб отримати символ, тоді як charAt
існує більше завдяки історичним причинам.
Різниця між ними лише в тому, що якщо символ з такою позицією відсутній, тоді []
поверне undefined
, а charAt
– порожній рядок:
let str = `Привіт`;
alert( str[1000] ); // undefined
alert( str.charAt(1000) ); // '' (порожній рядок)
Ми також можемо перебрати рядок посимвольно, використовуючи for..of
:
for (let char of "Привіт") {
alert(char); // П,р,и,в,і,т (char — спочатку "П", потім "р", потім "и" і так далі)
}
Рядки незмінні
В JavaScript рядки не можна змінювати. Змінити символ неможливо.
Спробуємо показати на прикладі:
let str = 'Ой';
str[0] = 'о'; // помилка
alert( str[0] ); // не працює
Можна створити новий рядок замість старого, записавши його в ту саму змінну.
Ось так:
let str = 'Ой';
str = 'о' + str[1]; // замінюємо рядок
alert( str ); // ой
В наступних розділах ми побачимо більше прикладів.
Зміна регістру
Методи toLowerCase() та toUpperCase() змінюють регістр символів:
alert( 'Інтерфейс'.toUpperCase() ); // ІНТЕРФЕЙС
alert( 'Інтерфейс'.toLowerCase() ); // інтерфейс
Або якщо ми хочемо перенести в нижній регістр конкретний символ:
alert( 'Інтерфейс'[0].toLowerCase() ); // 'і'
Пошук підрядка
Існує декілька способів для пошуку підрядка.
str.indexOf
Перший метод – str.indexOf(substr, pos).
Він шукає підрядок substr
в рядку str
, починаючи з позиції pos
, і повертає позицію, де знаходиться збіг, або -1
якщо збігів не було знайдено.
Наприклад:
let str = 'Віджет з ідентифікатором';
alert( str.indexOf('Віджет') ); // 0, тому що 'Віджет' було знайдено на початку
alert( str.indexOf('віджет') ); // -1, збігів не знайдено, пошук чутливий до регістру
alert( str.indexOf("ід") ); // 1, підрядок "ід" знайдено на позиції 1 (..іджет з ідентифікатором)
Необовʼязковий другий параметр pos
дозволяє нам почати пошук із заданої позиції.
Наприклад, перший збіг "ід"
знаходиться на позиції 1
. Щоб знайти наступний збіг, почнемо пошук з позиції 2
:
let str = 'Віджет з ідентифікатором';
alert( str.indexOf('ід', 2) ) // 9
Щоб знайти усі збіги, нам потрібно запустити indexOf
в циклі. Кожен новий виклик здійснюється з позицією після попереднього збігу:
let str = 'Хитрий, як лисиця, сильний, як Як';
let target = 'як'; // давайте знайдемо це
let pos = 0;
while (true) {
let foundPos = str.indexOf(target, pos);
if (foundPos == -1) break;
alert( `Знайдено тут: ${foundPos}` );
pos = foundPos + 1; // продовжуємо з наступної позиції
}
Той самий алгоритм можна записати коротше:
let str = "Хитрий, як лисиця, сильний, як Як";
let target = "як";
let pos = -1;
while ((pos = str.indexOf(target, pos + 1)) != -1) {
alert( pos );
}
str.lastIndexOf(substr, position)
Також є схожий метод str.lastIndexOf(substr, position), що виконує пошук від кінця рядка до його початку.
У ньому будуть перераховані збіги в зворотному порядку.
Існує незручність з indexOf
в умові if
. Ми не можемо помістити його в if
таким чином:
let str = "Віджет з ідентифікатором";
if (str.indexOf("Віджет")) {
alert("Є співпадіння"); // не працює
}
В прикладі вище alert
не відображається, оскільки str.indexOf("Віджет")
повертає 0
(це означає, що він знайшов збіг у початковій позиції). Це правильно, але if
вважає, що 0
– це false
.
Тому нам потрібно робити перевірку на -1
, як тут:
let str = "Віджет з ідентифікатором";
if (str.indexOf("Віджет") != -1) {
alert("Є співпадіння"); // тепер працює!
}
Трюк з побітовим НЕ
Один зі старих прийомів, який тут використовується, це побітовий оператор НЕ – ~
. Він перетворює число в 32-розрядне ціле число (вилучає десяткову частину, якщо вона є), а потім повертає всі біти в його двійковому представленні.
На практиці це означає просту річ: для 32-розрядних чисел значення ~n
рівне -(n+1)
.
Наприклад:
alert( ~2 ); // -3, те саме що -(2+1)
alert( ~1 ); // -2, те саме що -(1+1)
alert( ~0 ); // -1, те саме що -(0+1)
alert( ~-1 ); // 0, те саме що -(-1+1)
Як ми можемо бачити, ~n
рівне 0 лише при n == -1
(для будь якого 32-розрядного цілого числа n
)
Відповідно, проходження перевірки if ( ~str.indexOf("...") )
означає, що результат indexOf
відрізняється від -1
. Іншими словами, коли є збіг.
Таку перевірку іноді використовують як компактний indexOf
:
let str = "Віджет";
if (~str.indexOf("Віджет")) {
alert( 'Є співпадіння!' ); // Працює
}
Зазвичай використовувати можливості мови неочевидним способом не рекомендується, але цей трюк широко використовується в старому коді, тому це важливо розуміти.
Просто запамʼятайте: if (~str.indexOf(...))
означає “якщо знайдено”.
Проте, якщо бути точніше, через те, що великі числа обрізаються до 32 бітів оператором ~
, існують числа, для яких результат також буде 0
, найменше таке число ~4294967295=0
. Тому така перевірка буде працювати для рядків невеликої довжини.
Зараз такий трюк ми можемо побачити лише в старому коді, тому що в сучасному JavaScript є метод .includes
.
includes, startsWith, endsWith
Сучасніший метод str.includes(substr, pos) повертає true/false
в залежності від того чи є substr
в рядку str
.
Цей метод доцільно використовувати, коли потрібно перевірити чи є збіг, але не потрібна позиція:
alert( "Віджет з ідентифікатором".includes("Віджет") ); // true
alert( "Привіт".includes("Бувай") ); // false
Необовʼязковий другий аргумент pos
– це позиція з якої почнеться пошук:
alert( "Віджет".includes("ід") ); // true
alert( "Віджет".includes("ід", 3) ); // false, починаючи з 3-го символа, підрядка "ід" немає
Відповідно, методи str.startsWith та str.endsWith перевіряють, чи починається і чи закінчується рядок певним підрядком.
alert( "Віджет".startsWith("Від") ); // true, "Віджет" починається з "Від"
alert( "Віджет".endsWith("жет") ); // true, "Віджет" закінчується підрядком "жет"
Отримання підрядка
В JavaScript є 3 метода для отримання підрядка: substring
, substr
та slice
.
str.slice(start [, end])
-
Повертає частину рядка починаючи від
start
до (але не включно)end
.Наприклад:
let str = "stringify"; alert( str.slice(0, 5) ); // 'strin', підрядок від 0 до 5 (5 не включно) alert( str.slice(0, 1) ); // 's', від 0 до 1, але 1 не включно, тому лише символ на позиції 0
Якщо другий аргумент відсутній, тоді
slice
поверне символи до кінця рядка:let str = "stringify"; alert( str.slice(2) ); // 'ringify', з позиції 2 і до кінця
Також для
start/end
можна задати відʼємне значення. Це означає, що позиція буде рахуватися з кінця рядка:let str = "stringify"; // починаємо з 4-го символа справа, і закінчуємо на 1-му символі справа alert( str.slice(-4, -1) ); // 'gif'
str.substring(start [, end])
-
Повертає частину рядка між
start
таend
.Цей метод майже такий самий що і
slice
, але він дозволяє задатиstart
більше ніжend
.Наприклад:
let str = "stringify"; // для substring ці два приклади однакові alert( str.substring(2, 6) ); // "ring" alert( str.substring(6, 2) ); // "ring" // ...але не для slice: alert( str.slice(2, 6) ); // "ring" (те саме) alert( str.slice(6, 2) ); // "" (порожній рядок)
Відʼємні аргументи (на відміну від slice) не підтримуються, вони інтерпретуються як
0
. str.substr(start [, length])
-
Повертає частину рядка з позиції
start
, із заданою довжиноюlength
.На відміну від попередніх методів, цей дозволяє вказати довжину
length
замість кінцевої позиції:let str = "stringify"; alert( str.substr(2, 4) ); // 'ring', починаючи з позиції 2 отримуємо 4 символа
Перший аргумент може бути відʼємним, щоб рахувати з кінця:
let str = "stringify"; alert( str.substr(-4, 2) ); // 'gi', починаючи з позиції 4 з кінця отримуєму 2 символа
Давайте підсумуємо ці методи щоб не заплутатись:
Метод | вибирає… | відʼємні значення |
---|---|---|
slice(start, end) |
від start до end (end не включно) |
дозволяє відʼємні значення |
substring(start, end) |
між start та end |
відʼємні значення інтерпретуються як 0 |
substr(start, length) |
length символів від start |
дозволяє відʼємні значення start |
Усі вони можуть виконати задачу. Формально substr
має незначний недолік: він описаний не в основній специфікації JavaScript, а в Annex B, який охоплює лише функції браузера, які існують переважно з історичних причин. Тому не браузерні середовища, можуть не підтримувати його. Але на практиці це працює всюди.
З двох інших варіантів slice
дещо гнучкіший, він допускає негативні аргументи та коротший в записі. Отже, достатньо запамʼятати лише slice
з цих трьох методів.
Порівняння рядків
Як ми знаємо з розділу Оператори порівняння, рядки порівнюються символ за символом в алфавітному порядку.
Хоча, є деякі дивацтва.
-
Літера в малому регістрі завжди більша за літеру у великому:
alert( 'a' > 'Z' ); // true
-
Літери з діакритичними знаками “не в порядку”:
alert( 'Österreich' > 'Zealand' ); // true
Це може призвести до дивних результатів, якщо ми відсортуємо ці назви країн. Зазвичай люди очікують, що
Zealand
буде післяÖsterreich
.
Щоб зрозуміти, що відбувається, давайте розглянемо внутрішнє представлення рядків у JavaScript.
Усі рядки кодуються за допомогою UTF-16. Тобто: кожен символ має відповідний цифровий код. Існують спеціальні методи, які дозволяють отримати символ для коду і навпаки.
str.codePointAt(pos)
-
Повертає код символу на позиції
pos
:// літери в різному регістрі мають різні коди alert( "z".codePointAt(0) ); // 122 alert( "Z".codePointAt(0) ); // 90
String.fromCodePoint(code)
-
Створює символ за його кодом
code
alert( String.fromCodePoint(90) ); // Z
Ми також можемо додати юнікодні символи за їхніми кодами, використовуючи
\u
, за яким слідує шістнадцятковий код:// 90 – це 5a в шістнадцятковій системі числення alert( '\u005a' ); // Z
Тепер давайте подивимося на символи з кодами 65..220
(латинський алфавіт і трохи більше), створивши з них рядок:
let str = '';
for (let i = 65; i <= 220; i++) {
str += String.fromCodePoint(i);
}
alert( str );
// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
// ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜ
Бачите? Спочатку вводяться великі символи, потім кілька спеціальних, потім символи нижнього регістру та Ö
ближче до кінця виводу.
Тепер стає очевидним, чому a > Z
.
Символи порівнюються за їх числовим кодом. Більший код означає, що символ більше. Код для a
(97) більший за код для Z
(90).
- Усі малі літери йдуть після великих, оскільки їхні коди більші.
- Деякі літери, як-от
Ö
, стоять окремо від основного алфавіту. Тут його код більший за будь-що відa
доz
.
Правильне порівняння
«Правильний» алгоритм порівняння рядків є складнішим, ніж може здатися, тому що для різних мов – різні алфавіти.
Отже, браузеру потрібно знати, яку мову використовувати для порівняння.
На щастя, усі сучасні браузери (IE10- вимагає додаткової бібліотеки Intl.js) підтримують стандарт інтернаціоналізації ECMA-402.
Він забезпечує спеціальний метод для порівняння рядків різними мовами, дотримуючись їхніх правил.
Виклик str.localeCompare(str2) повертає ціле число, яке вказує, чи є str
меншим, рівним чи більшим за str2
відповідно до правил мови:
- Повертає відʼємне число, якщо
str
менше, ніжstr2
. - Повертає додатне число, якщо
str
більше, ніжstr2
. - Повертає
0
, якщо вони рівні.
Наприклад:
alert( 'Österreich'.localeCompare('Zealand') ); // -1
Цей метод насправді має два додаткові аргументи, зазначені в документації, що дозволяє йому вказати мову (типово взяту з середовища, порядок букв залежить від мови) і встановити додаткові правила, як-от чутливість до регістру або чи слід розглядати різницю між "a"
та "á"
.
Як усе влаштовано, Юнікод
Розділ заглиблюється у внутрішню частину рядків. Ці знання знадобляться вам, якщо ви плануєте мати справу з емодзі, рідкісними математичними чи ієрогліфічними символами чи іншими рідкісними символами.
Ви можете пропустити розділ, якщо не плануєте підтримувати їх.
Сурогатні пари
Усі часто використовувані символи мають 2-байтові коди. Літери в більшості європейських мов, цифри і навіть більшість ієрогліфів мають 2-байтове представлення.
Але 2 байти – це лише 65536 комбінацій, і цього недостатньо для кожного можливого символу. Тому рідкісні символи кодуються парою 2-байтових символів, які називаються «сурогатною парою».
Довжина таких символів – 2
:
alert( '𝒳'.length ); // 2, математичний символ "x" у верхньому регістрі
alert( '😂'.length ); // 2, емодзі -- обличчя зі сльозами радості
alert( '𩷶'.length ); // 2, рідкісний китайський ієрогліф
Зауважте, що сурогатні пари не існували на момент створення JavaScript, і тому мова не обробляє їх належним чином!
Насправді ми маємо один символ у кожному з наведених вище рядків, але length
показує довжину 2
.
String.fromCodePoint
і str.codePointAt
– це кілька рідкісних методів, які правильно працюють із сурогатними парами. Вони зʼявились в мові нещодавно. До них були лише String.fromCharCode і str.charCodeAt. Ці методи насправді такі ж, як fromCodePoint/codePointAt
, але не працюють із сурогатними парами.
Отримати символ може бути складно, оскільки сурогатні пари розглядаються як два символи:
alert( '𝒳'[0] ); // дивні символи...
alert( '𝒳'[1] ); // ...частини сурогатної пари
Зверніть увагу, що частини сурогатної пари не мають значення один без одного. Отже, сповіщення в прикладі вище насправді відображають сміття.
Технічно, сурогатні пари також можна виявити за їх кодами: якщо символ має код в інтервалі 0xd800..0xdbff
, то це перша частина сурогатної пари. Наступний символ (друга частина) повинен мати код в інтервалі 0xdc00..0xdfff
. За стандартом ці інтервали зарезервовані виключно для сурогатних пар.
У наведеному вище випадку:
// charCodeAt не підтримує сурогатні пари, тому дає коди для частин
alert( '𝒳'.charCodeAt(0).toString(16) ); // d835, між 0xd800 та 0xdbff
alert( '𝒳'.charCodeAt(1).toString(16) ); // dcb3, між 0xdc00 та 0xdfff
Більше способів роботи із сурогатними парами ви знайдете пізніше в розділі Ітеративні об’єкти. Для цього також є спеціальні бібліотеки, але немає достатньо відомої, щоб запропонувати її тут.
Діакритичні знаки та нормалізація
У багатьох мовах є символи, які складаються з основного символу з позначкою над/під ним.
Наприклад, буква a
може бути базовим символом для: àáâäãåā
. Найбільш поширені “складені” символи мають власний код у таблиці UTF-16. Але не всі, оскільки можливих комбінацій занадто багато.
Для підтримки довільних композицій UTF-16 дозволяє нам використовувати кілька юнікодних символів: основний символ, за яким слідує один або багато символів «позначок», які «прикрашають» його.
Наприклад, якщо у нас є S
, за яким слідує спеціальний символ “крапка зверху” (код \u0307
), він відображається як Ṡ.
alert( 'S\u0307' ); // Ṡ
Якщо нам потрібна додаткова позначка над літерою (або під нею) – не проблема, просто додайте потрібний символ позначки.
Наприклад, якщо ми додамо символ “крапка внизу” (код \u0323
), то матимемо “S з крапками зверху і знизу”: Ṩ
.
Наприклад:
alert( 'S\u0307\u0323' ); // Ṩ
Це забезпечує велику гнучкість, але також є цікава проблема: два символи візуально можуть виглядати однаково, але представлені різними юнікодними композиціями.
Наприклад:
let s1 = 'S\u0307\u0323'; // Ṩ, S + крапка зверху + крапка знизу
let s2 = 'S\u0323\u0307'; // Ṩ, S + крапка знизу + крапка зверху
alert( `s1: ${s1}, s2: ${s2}` );
alert( s1 == s2 ); // false, хоча на вигляд символи однакові (?!)
Щоб вирішити це, існує алгоритм “юнікодної нормалізації”, який приводить кожен рядок до єдиної “нормальної” форми.
Це реалізовано за допомогою str.normalize().
alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true
Цікаво, що в нашій ситуації normalize()
насправді об’єднує послідовність з 3 символів в один: \u1e68
(S з двома крапками).
alert( "S\u0307\u0323".normalize().length ); // 1
alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
Насправді це не завжди так. Причина в тому, що символ Ṩ
є “досить поширеним”, тому розробники UTF-16 включили його в основну таблицю і присвоїли йому код.
Якщо ви хочете дізнатися більше про правила та варіанти нормалізації – вони описані в додатку до стандарту Unicode: Unicode Normalization Forms, але для більшості практичних для цілей інформації з цього розділу достатньо.
Підсумки
- Є 3 види лапок. Зворотні лапки дозволяють рядку охоплювати кілька ліній і вбудовувати вирази
${…}
. - Рядки в JavaScript кодуються за допомогою UTF-16.
- Ми можемо використовувати спеціальні символи, такі як
\n
, і вставляти літери за допомогою їхнього юнікоду за допомогою\u...
. - Щоб отримати символ, використовуйте:
[]
. - Щоб отримати підрядок, використовуйте:
slice
абоsubstring
. - Щоб перевести рядок у нижній/верхній регістри, використовуйте:
toLowerCase/toUpperCase
. - Щоб знайти підрядок, використовуйте:
indexOf
, абоincludes/startsWith/endsWith
для простих перевірок. - Щоб порівняти рядки з урахуванням правил мови, використовуйте:
localeCompare
, інакше вони порівнюються за кодами символів.
Є кілька інших корисних методів у рядках:
str.trim()
– видаляє (“обрізає”) пробіли з початку та кінця рядка.str.repeat(n)
– повторює рядокn
разів.- …та багато іншого можна знайти в посібнику.
Рядки також мають методи пошуку/заміни регулярними виразами. Але це велика тема, тому пояснюється в окремому розділі Regular expressions.
Коментарі
<code>
, для кількох рядків – обгорніть їх тегом<pre>
, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)