Робота з об'єктами
JavaScript спроектовано на основі простої парадигми. В основі концепції є прості об'єкти. Об'єкт - це набір властивостей, і кожна властивість складається з імені та значення, асоційованого з цим ім'ям. Значення властивості може бути функція, яку можна назвати методом об'єкт. На додаток до об'єктів, вбудованих у браузер, ви можете визначити свої власні об'єкти. Цей розділ описує як користуватися об'єктами, властивостями, функціями та методами, а також як створювати власні об'єкти.
Огляд об'єктів
Об'єкти JavaScript, як і в багатьох інших мовах програмування, схожі на об'єкти реального життя. Концепцію об'єктів JavaScript легше зрозуміти, проводячи паралелі з об'єктами, що реально існують у житті.
JavaScript об'єкт — це самостійна одиниця, що має властивості і певний тип. Порівняємо, наприклад, із чашкою. У чашки є колір, форма, вага, матеріал, з якого вона виготовлена, і т.д. Так само, об'єкти JavaScript мають властивості, які визначають їх характеристики.
Об'єкти та властивості
JavaScript об'єкт має властивості, асоційовані з ним. Властивість об'єкта можна розуміти як змінну, закріплену за об'єктом. Властивості об'єкта по суті є тими самими змінними JavaScript, за винятком, що вони закріплені за об'єктом. Властивості об'єкта визначають його характеристики. Отримати доступ до властивості об'єкта можна за допомогою точкового запису:
objectName.propertyName;
Як і всі змінні JavaScript, ім'я об'єкта (яке також може бути змінною) та ім'я властивості є чутливими до регістру. Ви можете визначити властивість, вказавши його значення. Наприклад, давайте створимо об'єкт myCar і визначимо його властивості make , model , та year наступним чином:
var myCar = новий Object(); myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969;
Невизначені властивості об'єкта є undefined (а не null).
myCar.color; // undefined
Властивості об'єктів JavaScript також можуть бути доступні або задані за допомогою дужного запису (докладніше див. property accessors). Об'єкти іноді називаються асоціативними масивамиоскільки кожна властивість пов'язана з рядковим значенням, яке можна використовувати для доступу до нього. Так, наприклад, ви можете отримати доступ до властивостей об'єкту myCar таким чином:
myCar["make"] = "Ford"; myCar["model"] = "Mustang"; myCar["year"] = 1969;
Імена властивостей об'єкта можуть бути рядками JavaScript або тим, що може бути конвертовано в рядок, включаючи порожній рядок. Як би там не було, доступ до будь-якого імені властивості, яке містить невалідний JavaScript ідентифікатор (наприклад, ім'я властивості містить пробіл і тире або починається з цифри), може бути отриманий з використанням квадратних дужок. Цей спосіб запису також корисний, коли імена властивостей мають бути динамічно визначені (коли ім'я властивості не визначено до виконання). Приклади далі:
var myObj = новий Object(), str = "myString", rand = Math.random(), obj = новий Object(); myObj.type = "Dot syntax"; myObj["date created"] = "String with space"; myObj[str] = "String value"; myObj[rand] = "Random Number"; myObj[obj] = "Object"; myObj[""] = "Even an empty string"; console.log(myObj);
Зверніть увагу, що всі ключі з квадратними дужками перетворюються на тип String, оскільки об'єкти в JavaScript можуть мати як ключ тільки тип String. Наприклад, у наведеному вище коді, коли ключ obj додається в myObj , JavaScript викликає метод obj.toString () і використовує цей результуючий рядок як новий ключ.
Ви також можете отримати доступ до властивостей, використовуючи значення рядка, яке зберігається в змінній:
var propertyName = "make"; myCar[propertyName] = "Ford"; propertyName = "model"; myCar[propertyName] = "Mustang";
Ви можете користуватися квадратними дужками у конструкції for. in щоб виконати ітерацію всіх властивостей об'єкта, котрим вона дозволена.Щоб показати як це працює, наступна функція показує всі властивості об'єкта, коли ви передає в неї сам об'єкт та його ім'я як аргументи функції:
function showProps(obj, objName) < var result = ""; for (var i in obj) < if (obj.hasOwnProperty(i)) < result += objName + "." + i + "=" + obj[i] + "\n"; >> return result; >
Так що якщо викликати цю функцію так showProps(myCar, "myCar"), то отримаємо результат:
myCar.make = Ford; myCar.model = Mustang; myCar.year = 1969;
Перелік усіх властивостей об'єкту
Починаючи з ECMAScript 5, є три способи перерахувати всі властивості об'єкта (отримати їх список):
- цикли for. in Цей метод перебирає всі перераховані властивості об'єкта та його ланцюжок прототипів
- Object.keys(o) Цей метод повертає масив з усіма власними (ті, що в ланцюжку прототипів, не увійдуть до масиву) іменами властивостей об'єкта o .
- Object.getOwnPropertyNames(o) Цей метод повертає масив, що містить усі імена своїх властивостей (перелічуваних і неперелічуваних) об'єкта o .
До ECMAScript 5 не було вбудованого способу перерахувати всі властивості об'єкта. Однак це можна зробити за допомогою наступної функції:
function listAllProperties(o) < var objectToInspect; var result = []; for ( objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect) ) < result = result.concat(Object.getOwnPropertyNames(objectToInspect)); >return result; >
Це може бути корисним для виявлення прихованих (hidden) властивостей (властивості в ланцюжку прототипу, які недоступні через об'єкт, у разі, якщо інша властивість має таку ж ім'я в попередній ланці з ланцюжка прототипу). Перерахувати доступні властивості можна, якщо видалити дублікати з масиву.
Створення нових об'єктів
JavaScript містить набір вбудованих об'єктів. Ви також можете створювати свої об'єкти. Починаючи з JavaScript 1.2, можна створювати об'єкт за допомогою ініціалізатора об'єкта.Інший спосіб - створити функцію-конструктор і зробити екземпляр об'єкта за допомогою цієї функції та оператора new.
Використання ініціалізаторів об'єкту
Крім створення об'єктів за допомогою функції-конструктора, ви можете створювати об'єкти і іншим, особливим способом. Фактично, ви можете записати об'єкт синтаксично, і його буде створено інтерпретатором автоматично під час виконання. Ця синтаксична схема наведена нижче:
var obj = < property_1: value_1, // property_# may be an identifier. 2: value_2, // or a number. //. "property n": value_n, >; // or a string
тут obj – це ім'я нового об'єкта, кожне property_i – це ідентифікатор (ім'я, число чи рядковий літерал), і кожен value_i – це значення, призначені property_i . Ім'я obj та посилання об'єкта на нього необов'язкове; якщо далі вам не потрібно буде посилатися на цей об'єкт, то вам не обов'язково призначати об'єкт змінної. (Зверніть увагу, що вам потрібно обернути літерал об'єкта в дужки, якщо об'єкт знаходиться в місці, де очікується інструкція, щоб інтерпретатор не переплутав його з блоком.)
Якщо об'єкт створено за допомогою ініціалізатора об'єктів на вищому рівні скрипта, JavaScript інтерпретує об'єкт кожного разу, коли аналізує вираз, що містить об'єкт, записаний як літерал. Плюс, якщо користуватися функцією ініціалізатором, то він створюватиметься щоразу, коли функція викликається.
Наступна інструкція створює об'єкт і призначає його змінною x , коли вираз cond є істинним.
Наступний приклад створює об'єкт myHonda із трьома властивостями. Зауважте, що властивість engine це також об'єкт зі своїми власними властивостями.
Ви також можете використовувати ініціалізатор об'єкта для створення масивів. Дивитися array literals.
До JavaScript 1.1 не було можливості скористатися ініціалізаторами об'єкта. Єдиний спосіб створювати об'єкти — це користуватися функціями-конструкторами або іншими об'єктами, призначеними для цієї мети.Дивіться Using a constructor function.
Використання функції конструктора
Інший спосіб створити об'єкт у два кроки описаний нижче:
- Визначте тип об'єкта, написавши функцію-конструктор. Назва такої функції, як правило, починається з великої літери.
- Створіть екземпляр об'єкта за допомогою ключового слова new.
Щоб визначити тип об'єкта, створіть функцію, яка визначає тип об'єкта, його ім'я, властивості та методи. Наприклад, припустимо, що ви хочете створити тип об'єкта для опису машин. Ви хочете, щоб об'єкт цього типу називався car , і ви хочете, щоб він мав властивості make, model, і year. Щоб це зробити, напишіть наступну функцію:
function Car(make, model, year)
Зауважте, що використовується this щоб надати значення (передані як аргументи функції) властивостям об'єкта.
Тепер ви можете створити об'єкт, званий mycar , таким чином:
var mycar = new Car("Eagle", "Talon TSi", 1993);
Ця інструкція створює об'єкт типу Car з посиланням на mycar і надає певні значення його властивостям. Значенням mycar.make стане рядок "Eagle", mycar.year - це ціле число 1993 і так далі.
Ви можете створити стільки об'єктів car, скільки потрібно просто викликаючи new . Наприклад:
var kenscar = new Car("Nissan", "300ZX", 1992); var vpgscar = new Car("Mazda", "Miata", 1990);
Об'єкт може мати властивість, яка буде іншим об'єктом. Наприклад, далі визначається об'єкт типу Person наступним чином:
функція Person(name, age, sex)
і потім створити два нових екземпляри об'єктів Person як показано далі:
var rand = New Person("Rand McKinnon", 33, "M"); var ken = New Person("Ken Jones", 39, "M");
Потім ви можете переписати визначення car і включити в нього властивість owner , якому призначити об'єкт person наступним чином:
function Car(make, model, year, owner)
Потім, щоб створити екземпляри нових об'єктів, виконайте такі інструкції:
var car1 = new Car("Eagle", "Talon TSi", 1993, rand); var car2 = new Car("Nissan", "300ZX", 1992, ken);
Зауважте, що замість того, щоб передавати рядок, літерал або ціле число при створенні нових об'єктів, у виразах вище передаються об'єкти rand і ken як аргумент функції. Тепер, якщо вам потрібно дізнатися ім'я власника car2, це можна зробити так:
Зауважте, що у будь-який час ви можете додати нову властивість раніше створеному об'єкту. Наприклад, вираз
додає властивість color car1, і встановлює його значення рівним "black." Як би там не було, це не впливає на будь-які інші об'єкти. Щоб додати нову властивість всім об'єктам одного типу, ви повинні додати властивість визначення типу об'єкта car .
Використання методу Object.create
Об'єкти також можна створювати за допомогою методу Object.create. Цей метод дуже зручний, тому що дозволяє вам вказувати об'єкт прототип для нового об'єкта без визначення функції конструктора.
// Список властивостей і методів для Animal var Animal = < type: "Invertebrates", // Значення type за замовчуванням displayType: function () < // Метод тип об'єкта Animal console.log(this.type); >, >; // Створюємо об'єкт Animal var animal1 = Object.create(Animal); animal1.displayType(); // Виведе: Invertebrates // Створюємо об'єкт Animal та привласнюємо йому type = Fishes var fish = Object.create (Animal); fish.type = "Fishes"; fish.displayType(); // Виведе: Fishes
успадкування
Усі об'єкти JavaScript успадковуються як мінімум від іншого об'єкта. Об'єкт, від якого відбулося успадкування називається прототипом, і успадковані властивості можуть бути знайдені в об'єкті prototype конструктора.
Індекси властивостей об'єкту
У JavaScript 1.0 ви можете послатися на властивості об'єкта або на його ім'я, або на його порядковому індексі. У JavaScript 1.1 і пізніше, якщо ви спочатку визначили властивість на ім'я, ви завжди повинні посилатися на нього по його імені, і якщо ви спочатку визначили властивість за індексом, то повинні посилатися на нього за його індексом.
Це обмеження накладається, коли ви створюєте об'єкт і його властивості за допомогою функції конструктора (як ми це робили раніше з типом Car ) і коли ви визначаєте індивідуальні властивості явно (наприклад, myCar.color = "red"). Якщо ви спочатку визначили властивість об'єкта через індекс, наприклад, myCar[5] = "25 mpg" , то згодом послатися на цю властивість можна тільки так myCar[5] .
Виняток із правил - об'єкти, що відображаються з HTML, наприклад масив forms . Ви завжди можете послатися на об'єкти в цих масивах або використовуючи їх індекс (який ґрунтується на порядку появи в HTML документі), або за їхніми іменами (якщо вони були визначені). Наприклад, якщо другий html-тег у документі має значення атрибута NAME, що дорівнює "myForm", ви можете послатися на цю форму ось так: document.forms[1] або document.forms["myForm"] або document.myForm .
Визначення властивостей типу об'єкта
Ви можете додати властивість до раніше визначеного типу об'єкта, скориставшись спеціальною властивістю prototype. Через prototype створюється властивість, єдина всім об'єктів даного типу, а чи не одного примірника цього об'єкта. Наступний код демонструє це, додаючи властивість color всіх об'єктів типу car , а потім присвоюючи значення властивості color об'єкта car1 .
Car.prototype.color = null; car1.color = "black";
Дивіться властивість prototype об'єкта Function у Довіднику JavaScript для отримання деталей.
Визначення методів
Метод - Це функція, асоційована з об'єктом або, простіше кажучи, метод - це властивість об'єкта, що є функцією. Методи визначаються так само, як і звичайні функції, за винятком, що вони присвоюються властивості об'єкта. Наприклад, ось так:
objectName.methodname = function_name; var myObj = < myMethod: function (params) < // . do something >, >;
де objectName - це існуючий об'єкт, methodname - це ім'я, яке ви надаєте методу, і function_name - це ім'я самої функції.
Потім ви можете викликати метод у контексті об'єкта таким чином:
object.methodname(params);
Ви можете визначати методи типу об'єкта, включаючи визначення методу в функцію конструктора об'єкта. Наприклад, ви можете визначити функцію, яка форматує та відображає властивості до цього певних об'єктів car . Наприклад,
function displayCar()
де pretty_print – це функція відображення горизонтальної лінії та рядка. Зауважте, що це використання дозволяє посилатися на об'єкт, якому належить метод.
Ви можете зробити цю функцію методом car, додавши інструкцію
this.displayCar = displayCar;
визначення об'єкта. Таким чином, повне визначення car набуде наступного вигляду:
function Car(make, model, year, owner)
Тепер ви можете викликати метод displayCar для кожного з об'єктів, як показано нижче:
car1.displayCar(); car2.displayCar();
Використання цього посилання на об'єкт
JavaScript має спеціальне ключове слово this, яке ви можете використовувати всередині методу, щоб посилатися на поточний об'єкт. Припустимо, у вас є функція validate, яка звіряє властивість value, переданого їй об'єкта з деякими верхнім та нижнім значеннями:
function validate(obj, lowval, hival) < if (obj.value < lowval || obj.value >hival) alert("Invalid Value!"); >
Ви можете викликати цю функцію validate в кожному елементі форми, в обробці події onchange . Використовуйте це для доступу до цього елемента, як це зроблено нижче:
У загальному випадку цепосилається на об'єкт, що викликав метод.
Через це можна звернутися і до батьківської форми елемента, скориставшись властивістю форми. У наступному прикладі форма myForm містить елемент введення Text та кнопку button1 . Коли користувач натискає кнопку, значення об'єкта Text призначається ім'я форми. Обробник подій кнопки onclick користується this.form, щоб послатися на поточну форму, myForm .
Визначення гетерів та сеттерів
Геттер (від англ. get – отримати) — це метод, який набуває значення певної властивості. Сеттер (Від англ. Set - присвоїти) - це метод, який надає значення певній властивості об'єкта. Ви можете визначити гетери та сеттери для будь-яких з вбудованих або певних об'єктів, які підтримують додавання нових властивостей. Синтаксис визначення геттерів та сеттерів використовує літеральний синтаксис об'єктів.
Нижче проілюстровано, як можуть працювати гетери та сеттери в об'єкті, визначеному користувачем:
var o = < a: 7, get b() < return this.a + 1; > set c(x) < this.a = x / 2; >, >; console.log(o.a); // 7 console.log(o.b); //8 o.c = 50; console.log(o.a); // 25
Об'єкт o отримає такі характеристики:
- o.a - число
- o.b - геттер, який повертає o.a плюс 1
- o.c — сетер, який надає значення o.a половині значення, яке передано в o.c
Слід зазначити, що імена функцій, зазначені у літеральної формі "[gs]et propertyName() < >" не будуть насправді іменами геттера і сеттера. Щоб задати як геттер і сеттер функції з явно певними іменами, використовуйте метод Object.defineProperty (або його застарілий аналог Object.prototype.__defineGetter__ ).
У коді нижче показано, як за допомогою геттера та сеттера можна розширити прототип об'єкта Date та додати йому властивість year, яка буде працювати у всіх екземплярів класу Date . Цей код використовує існуючі методи класу Date - getFullYear та setFullYear для роботи геттера та сеттера.
Визначення геттера та сеттера для властивості year :
var d = Date.prototype; Object.defineProperty(d, "year", < get: function () < return this.getFullYear(); >, set: function (y) < this.setFullYear(y); >, >);
Використання властивості year заданого геттером та сеттером:
var now = New Date(); console.log(now.year); // 2000 now.year = 2001; // 987617605170 console.log(now); // Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
В принципі, гетери та сеттери можуть бути або:
- визначено під час використання Ініціалізаторів об'єкта, або
- додані існуючому об'єкту у будь-який момент, при використанні методів додавання гетерів та сеттерів.
Коли визначення геттера і сеттера використовує ініціалізатори об'єкта, все що вам потрібно, це доповнити геттер префіксом get а сеттер префіксом set . присвоєння властивості).
Геттери і сеттери можуть бути додані існуючому об'єкту в будь-який момент, за допомогою методу Object.defineProperties . а значення - об'єкти що визначають геттер і сеттер створюваних властивостей. такі ж гетер та сетер, як і в прикладі вище:
var o = < a: 0 >; x / 2; >, >, >); o.c = 10; 'a' console.log(o.b); // Запускає геттер, який повертає a + 1 (тобто 6)
Те, яку з двох форм використовувати для визначення властивостей, залежить від вашого стилю програмування і задачі, що стоїть перед вами. природна. Однак, не рідко, друга форма є єдиною можливою, у випадках, коли ви працюєте з існуючим об'єктом без доступу до його Друга форма найкращим чином відображає динамічну природу JavaScript - але може зробити код складним для читання та розуміння.
Видалення властивостей
Ви можете видалити властивість за допомогою оператора delete . Наступний код показує як видалити властивість.
// Create a new object, myobj, with 2 properties, a and b. var myobj = новий Object(); myobj.a = 5; myobj.b = 12; //Removes the a property, leaving myobj with only the b property. delete myobj.a;
Ви також можете скористатися delete, щоб видалити глобальну змінну, якщо ключове слово var не було використане при її оголошенні:
Дивіться [delete](Expressions_and_operators#delete), щоб отримати додаткову інформацію.
Порівняння об'єктів
У JavaScript об'єкти мають тип посилання. Два окремі об'єкти ніколи не будуть рівними, навіть якщо вони мають рівний набір властивостей. Тільки порівняння двох посилань на той самий об'єкт поверне true.
// Дві змінні посилаються на два об'єкти з однаковими властивостями var fruit = <name: "apple">; var fruitbear = <name: "apple">; fruit == fruitbear; // поверне false fruit === fruitbear; // поверне false
// Дві змінні посилаються однією загальний об'єкт var fruit = < name: "apple" >; var fruitbear = fruit; // привласним змінної fruitbear посилання на об'єкт fruit // тепер fruitbear і fruit посилаються на той самий об'єкт fruit == fruitbear; // поверне true fruit === fruitbear; // Поверне true
fruit.name="grape"; console.log(fruitbear); // поверне < name: "grape" >замість
Дивіться також
- Для детального вивчення читайте детальніше про об'єктну модель JavaScript.
- Для вивчення класів ECMAScript 2015 (новий спосіб визначення об'єктів) читайте розділ класи JavaScript.
Рядки у JavaScript. Методи об'єкту String
У цій статті розберемо, як створювати рядки в JavaScript. Вивчимо основні методи роботи з ними, а також розглянемо, як відбувається їх порівняння.
Що таке рядок?
Рядок ( String ) - це тип даних JavaScript для подання довільної послідовності символів.
У JavaScript для рядків завжди використовується кодування UTF-16. Вона не залежить від того, яке кодування встановлено для HTML-сторінки.
Створення рядка здійснюється дуже просто.Для цього необхідно просто потрібні символи помістити між:
- одинарними лапками';
- подвійними лапками";
- зворотними лапками`.
let name1 = 'Alexander'; let name2 = "Alexander"; let name3 = `Alexander`;
У наведеному вище прикладі ми маємо три рядки, призначені різним змінним. Щоб переконатися, що це всі рядки, ми можемо перевірити тип змінної:
console.log(typeof(name1)); // string console.log(typeof(name2)); // string console.log(typeof(name3)); // string
Важливо знати, що рядки в JavaScript незмінні. Це означає, що після створення рядка її вміст змінити не можна:
let str = 'Go'; str[0] = 'g'; // Змінимо перший символ рядка на "g" console.log (str); // "Go"
Як бачите, змінити рядок нам не вдалося. Щоб це зробити, нам потрібно просто створити новий рядок і, наприклад, присвоїти його тій самій змінній:
let str = 'Go'; str = 'g' + str[1]; // "go" console.log(str); // "go"
Рядок може не містити жодного символу:
const str1 = ''; const str2 = ""; const str3 = ``;
Такі рядки називають порожніми.
Конкатенація рядків
У JavaScript конкатенація (об'єднання) двох або більше рядків в один виконується за допомогою оператора +:
const firstName = 'Marcus'; const lastName = 'Wolfe'; const fullName = firstName + '' + lastName; console.log(fullName); // "Marcus Wolfe"
У цьому прикладі між рядками, що містяться в змінних firstName і lastName ми додали пробіл ( ' ' ).
Інший спосіб складання рядків у JavaScript - це використовувати метод concat() :
const firstName = 'Marcus'; const lastName = 'Wolfe'; const fullName = firstName.concat('', lastName); console.log(fullName); // "Marcus Wolfe"
У JavaScript ви можете також використовувати шаблонні рядки для конкатенації рядків:
const firstName = 'Marcus'; const lastName = 'Wolfe'; const fullName = `${firstName} ${lastName}`; console.log(fullName); // "Marcus Wolfe"
Шаблонні рядки
Як ми зазначали вище, шаблонні рядки - це спосіб створення рядків за допомогою зворотних лапок ( ` ). Вони з'явилися в мові значно пізніше, ніж звичайні рядки і мають на відміну від них ряд додаткових можливостей.
1. Шаблонний рядок, на відміну від звичайного рядка, можна розташовувати на кількох рядках:
const mySkill = `* HTML * CSS * JavaScript`;
Для створення багаторядкових рядків за допомогою одинарних та подвійних лапок потрібно використовувати символ перекладу рядка ( \n ):
const mySkill = '* HTML\n* CSS\n* JavaScript';
Розташувати такий рядок на кількох рядках можна тільки з використанням оператора +:
const mySkill = '* HTML\n' + '* CSS\n' + '* JavaScript';
2. Ще одна відмінність шаблонного рядка полягає в тому, що він може включати вираз ${ .
const name = 'Alexander'; const greeting = `Hi, ${name.toUpperCase()}.`; // "Hi, ALEXANDER."
Екранування символів
У JavaScript включення символу в рядок, який використовується для її створення, здійснюється за допомогою екранування.
const str1 = "He said, \"I love JavaScript!"" // He said, "I love JavaScript!" $echo\`hello``; // $echo`hello`
Якщо цього не зробити, то буде видано помилку:
str = "He said, "I learned from itchief!""; // Uncaught SyntaxError: Unexpected identifier 'I'
Крім екранування в даному випадку ви можете просто використовувати іншу лапку:
const str1 = 'He said, "I love JavaScript!"' // He said, "I love JavaScript!" ``; // $ echo `hello`
Крім цього, символ екранування також використовується для вставки спецсимволів у текст.
- \n - переклад рядка;
- \ - зворотний сліш;
- t - знак табуляції.
Довжина рядка
Отримання довжини рядка, тобто кількості символів з яких вона складається, виконується JavaScript за допомогою властивості length :
const mystr = 'Мій рядок тексту';// отримуємо кількість символів const len = mystr.length;
Доступ до символів
Витягти певний символ рядка можна за допомогою квадратних дужок .
const str = 'Welcome'; // отримаємо перший символ console.log(str[0]); // "W" // отримаємо другий символ console.log(str[1]); останній символ console.log(str[str.length - 1]);
При передачі індексу неіснуючого символу отримаємо undefined :
const name = 'Zoe'; // отримаємо перший символ console.log(str[-1]); // undefined // отримаємо другий символ console.log(str[3]);
Крім цього, отримати символ рядка за його порядковим номером можна за допомогою спеціальних призначених для цього випадку методів: charAt і at.
const str = 'Welcome'; // отримаємо перший символ console.log(str.charAt[2]); // "l" // отримаємо другий символ console.log(str.at[3]); "
Метод at з'явився в мові пізніше і на відміну від chartAt він більш гнучкий.
const fruit = 'Banana'; // отримаємо останній символ console.log(fruit.at[-1]); "n"
Ще це можна зробити за допомогою slice:
const str = 'Welcome'; // отримаємо перший символ console.log(str.slice(2, 0)); // "c"
Якщо вам потрібно посимвольно перебрати рядок, можна скористатися циклами. Наприклад, for або for..of :
const name = 'Tess'; // довжина рядка const len = name.length; // for for (let i = 0; i < len; i++) , "e", "s", "s" } // for..of for (let char of name) { console.log(char); // "T", "e", "s", "s " }
Методи рядків
Незважаючи на те, що рядки є примітивним типом даних, JavaScript вони поводяться як об'єкти. Тому, при роботі з ними, нам доступні різні властивості та методи. Наприклад:
// властивість length щоб одержати довжини рядка 'Hello'.length; // 5 // метод concat для з'єднання рядків 'Hello'.concat(', Alexander'); // "Hello, Alexander"
Як це працює у JavaScript? Тут все дуже просто. Коли відбувається звернення до властивості або методу, рядок повертається до спеціальної обгортки new String() . Таким чином створюється новий екземпляр класу String , який має у свою чергу доступ до цих властивостей та методів. Тобто по суті движок JavaScript у собі робить щось таке:
// тип даних 'Hello' typeof 'Hello'; // "string" // тип даних new String('Hello') typeof new String('Hello'); // "object" (new String('Hello')).length; // 5 (new String('Hello')).concat(', Alexander'); // "Hello, Alexander"
Але використовувати JavaScript new String() безпосередньо для створення рядків не потрібно . Він застосовується, як ми вже зазначили вище автоматично, як обгортка над рядком, щоб ми з нею могли працювати як з об'єктом.
Саму функцію String без new можна використовувати, коли потрібно привести деяке значення до рядка:
String(5); // "5" String (true); // "true"
Інший спосіб перетворити значення на рядок – це використовувати метод toString() :
(5).toString(); // "5" true.toString(); // "true"
У String міститься багато методів для виконання різних операцій над рядками. Деякі з них ми вже розглянули вище. Це: concat(), at(), slice() та інші. Тепер розберемо які є цікаві методи в String для роботи з рядками.
1. Методи для пошуку підрядка у рядку:
- indexOf(substring [, start]) – повертає індекс, з якого починається шуканий підрядок у рядку;
- lastIndexOf(substring, [, start]) – те саме, що indexOf , лише пошук ведеться з кінця рядка.
const vegetables = 'Tomato, Potato, Carrot, Tomato'; vegetables.indexOf('Tomato', 5); // 24 const fruits = 'Banana, Peach, Pear, Peach'; fruits.lastIndexOf('Peach', 10); // 8
Параметр start не є обов'язковим. Він використовується, коли потрібно вказати, з якого символу рядка необхідно почати пошук. Якщо його не передати методу, пошук буде вестися з початку рядка.
const vegetables = 'Tomato, Potato, Carrot, Tomato'; vegetables.indexOf('Tomato'); // 0 const fruits = 'Banana, Peach, Pear, Peach'; fruits.lastIndexOf('Peach'); // 21
Якщо зазначений підрядок не знайдено, то ці методи як результат повертають значення -1 .
const vegetables = 'Tomato, Potato, Carrot, Tomato'; vegetables.indexOf('Broccoli'); // -1 const fruits = 'Banana, Peach, Pear, Peach'; fruits.lastIndexOf('Peach', 5); // -1
У разі коли потрібно перевірити, чи містить зазначений рядок шуканий, можна просто скористатися методом includes :
const vegetables = 'Tomato, Potato, Carrot, Tomato'; vegetables.includes('Carrot'); // true // через indexOf теж можна зробити, але трохи довше vegetables.indexOf('Carrot') > -1; // true
Цей метод повертає true , якщо знайдений рядок. В іншому випадку false .
Для пошуку з певної позиції її необхідно просто передати в другий аргумент includes :
const file = 'index.html'; file.includes('.html', file.length - 5); // true
Перевірити початок і кінець рядка на відповідність JavaScript можна дуже просто за допомогою спеціальних методів startsWith і endsWith :
const href = 'https://itchief.ru/javascript/'; href.startsWith('https://itchief.ru'); // true const file = 'index.html'; file.endsWith('.html'); // true
2. Методи отримання підрядки:
- substring(start [, end]) – частина рядка між start та end (не включаючи);
- substr(start [, length]) – частина рядка, що починається з індексу start довжиною length;
- slice(start [, end]) – частина рядка між start та end (не включаючи);
Приклади використання методу substring:
const greeting = 'Hello, Bob! How are you?'; // якщо другий аргумент не вказано, то до кінця рядка greeting.substring(7); // "Bob! How are you?" greeting.substring(7, 10); // " Bob " // якщо start більше end, то спрацює також, якби аргументи помінялися місцями greeting.substring(10, 7); // " Bob " // якщо аргументи рівні, отримаємо порожній рядок greeting.substring(7, 7); // "" // Негативні аргументи інтерпретуються як 0 greeting.substring(5, -2); // "Hello"
Приклади використання методу substr:
const greeting = 'Hello, Bob! How are you?'; // якщо другий аргумент не вказано, то до кінця рядка greeting.substr(7); // "Bob! How are you?" // другий аргумент відповідає за кількість символів, що повертаються greeting.substr(7, 3); // " Bob " / / Якщо перший аргумент негативний, то стартовий індекс відраховується з кінця greeting.substr (-17, 3); // "Bob"
Приклади використання методу slice:
const greeting = 'Hello, Bob! How are you?'; // якщо другий аргумент не вказано, то до кінця рядка greeting.slice (7); // "Bob! How are you?" // до end (не включаючи) greeting.slice (7, 10); // "Bob" // якщо start більше або дорівнює end, то отримаємо порожній рядок greeting.slice (10, 7); // " " // якщо аргумент негативний, індекс відлічується з кінця greeting.slice(-17, -14); // "Bob"
3. Розбиття рядка на масив рядків у JavaScript виконується за допомогою методу split:
const nums = 'One, Two, Three'; // покажчик для поділу рядка передається до першого аргументу nums.split(','); // ['One', 'Two', 'Three'] nums.split('One,'); // ['', 'Two,Three'] // обмеження кількість елементів, які будуть включені в масив, задається у другому аргументі nums.split(',', 2); // ['One', 'Two'] // якщо вказати як роздільника порожній рядок, то рядок буде розділена посимвольно nums.split('', 5); // ['O', 'n', 'e', ',', 'T']
Перевертання рядка з використанням split:
const str='Home'; const reverseStr = str.split('').reverse().join(); console.log(reverseStr); // "emoH"
Тут за допомогою split() ми спочатку розбиваємо рядок по роздільнику на масив рядків, кожен з яких це окремий символ. Після цього за допомогою reverse() інвертуємо масив, і наприкінці за допомогою join() назад перетворимо його на рядок.
4. Методи, за допомогою яких можна в рядку замінити pattern на replacement:
- replace(pattern, replacement);
- replaceAll(pattern, replacement) .
Як pattern можна використовувати рядок або регулярний вираз, а для replacement – рядок або функцію.
const nums = 'One, Two, Three, Two'; // замінимо перший знайдений рядок "Two" на "Six" nums.replace('Two', 'Six'); // One, Six, Three, Two // замінимо всі знайдені рядки "Two" на "Six" nums.replaceAll('Two', 'Six'); // One, Six, Three, Six
У цьому прикладі за допомогою методу replace замінили в nums підрядок 'Two' на 'Six' . Для цього ми як перший аргумент передали в replace рядок, який потрібно замінити. А в другому аргумент рядок, на який його потрібно замінити. За допомогою replaceAll ми замінили всі входження 'Two' на 'Six' .
Використання replaceAll для видалення прогалин з рядка:
const str = 'ABC'; const strWithoutSpaces = str.replaceAll('', ''); console.log(strWithoutSpaces); // ABC
Якщо потрібно прибрати інший символ із рядка:
'Football'.replaceAll('o', ''); // "Ftball"
Отримання коду символу з таблиці UTF-16 JavaScript здійснюється за допомогою методу charCodeAt :
// Повертає число від 0..65535 '@'.charCodeAt(); // 64 // отримаємо код першого символу рядка '@8'.charCodeAt(); // 64 // отримаємо код символу 8 '@8'.at(1).charCodeAt(); // 56
Статичний метод String.fromCharCode() дозволяє сформувати рядок із зазначених числових кодів символів:
String.fromCharCode(64); // "@" String.fromCharCode (64, 56); // "@8"
JavaScript спочатку був заснований на кодуванні UTF-8, яке передбачало 2 байти на один символ.Але пізніше цього виявилося замало уявлення всіх символів. Тому для кодування деяких символів використовується 4 байти:
// якщо використовувати charCodeAt, то отримаємо лише перші 2 байти, а не 4 '😀'.charCodeAt(); // 55357 // для отримання коду символу, що кодується 4 байтами '😀'.codePointAt(); // 128512 '👋'.codePointAt(); // 128075
Для отримання кодів 4-байтних символів необхідно замість charCodeAt() використовувати codePointAt() . Також і для складання рядка із заданих кодів слід замість String.fromCharCode() використовувати String.fromCodePoint() :
String.fromCodePoint(128075, 44, 32, 66, 111, 98, 33); // "👋, Bob!"
Метод repeat дозволяє створити рядок, що складається із зазначеної кількості повторень інший:
'Bob! '+' Yes! '.repeat(3); // "Bob! Yes! Yes! Yes!"
Методи padStart та padEnd дозволяють доповнити рядок до вказаної довжини заданим текстом:
// початок рядка '0312'.padStart(16, '*'); // "************0312" // у кінець рядка 'About JavaScript'.padEnd(20, '.'); // About JavaScript.
Методи toLowerCase і toUpperCase призначені для перетворення відповідно символів рядка в малі та великі.
let myString = "Welcome to itchief!"; let upperCaseString = myString.toUpperCase(); let lowerCaseString = myString.toLowerCase(); console.log(upperCaseString); // "WELCOME TO ITCHIEF!" console.log(lowerCaseString); // "welcome to itchief!"
Порівняння рядків
Порівняння рядків у JavaScript виконується посимвольно, за їх кодами:
'W'.charCodeAt(); // 87 'w'.charCodeAt(); // 119
Як ми вже зазначили вище, рядки порівнюються посимвольно. Тобто спочатку порівнюються перші символи. Якщо їх коди не рівні, порівняння завершується. У цьому випадку той рядок буде більшим, у якого код символу більший. В іншому випадку здійснюється перехід до порівняння других символів і таке інше:
Тут порівняння закінчується другому символі, оскільки їх коди не рівні (код 'e' більше 'b' ).
Якщо при порівнянні закінчується один із рядків, то більшим вважається той, який довше:
'Emma' === 'Emma'; // true 'Anna'! == 'Anna'; // false '007' == 7; // true, у разі рядок '007' наводиться до числа 7 '15px' == 15; // false, у разі рядок '15px' наводиться до NaN
Крім цього, JavaScript має метод localeCompare() , який дозволяє порівняти рядки з урахуванням мови та певних правил:
localeCompare(compareString[, locales[, options]])
Наприклад, перевіримо на рівність рядка без урахування регістру в локалі 'ru' :
const str1 = 'ГАРБУД'; const str2 = 'Гарбуз'; if (str1.localeCompare(str2, 'ru', {sensitivity: 'accent'}) === 0) { console.log('Рядки рівні'); } else { console.log('Рядки не рівні'); }
За допомогою параметра sensitivity вказуємо, що потрібно ігнорувати регістр та діактричні знаки при порівнянні рядків.
Як результат localeCompare() повертає число:
- від'ємне число – перший рядок менший за другий;
- 0 – рівні;
- позитивне число – перший рядок більший за другий;
У наступному прикладі відсортуємо масив імен відповідно до поточної мови користувача:
const names = ['Володимир', 'Євген', 'Maïa', 'Bob', 'Linda', 'Ірина']; // сортування відповідно до поточної локалі names.sort((a, b) => a.localeCompare(b)); console.log(names); // ["Володимир", "Євген", "Ірина", "Bob", "Linda", "Maïa"]