JavaScript дозволяє працювати з примітивами (рядок, число, тощо) так само як з об’єктами. Вони також надають методи для роботи. Ми вивчимо їх найближчим часом, але спочатку подивимось як воно працює, тому що примітиви не є об’єктами (і тут ми зробимо це ще більш зрозумілим).
Розгляньмо різницю між примітивами та об’єктами.
Примітив
- є значенням примітивного типу
- існує 7 типів примітивів:
string
,number
,bigint
,boolean
,symbol
,null
таundefined
.
Об’єкт
- можна зберігати декілька значень як властивості.
- може бути створений за допомогою
{}
, наприклад:{name: "Іван", age: 30}
. В JavaScript існують й інші об’єкти: функції — це теж об’єкти.
Одна з цікавих речей щодо об’єктів полягає в тому, що ми можемо зберігати функцію як одну з його властивостей.
let john = {
name: "John",
sayHi: function() {
alert("Привіт, друже!");
}
};
john.sayHi(); // Привіт, друже!
Отже, ми створили об’єкт john
з методом sayHi
.
Вже існує багато вбудованих об’єктів, які працюють з датами, помилками, елементами HTML і т.д. Вони мають різні властивості і методи.
Але за все потрібно платити!
Об’єкти “важчі”, ніж примітиви. Вони вимагають додаткових ресурсів для підтримки внутрішньої обробки.
Примітив як об’єкт
Маємо парадокс, з яким зустрічається автор JavaScript:
- Є багато речей, які можна було б зробити з примітивом-рядком або числом. Було б добре отримати доступ до цих методів.
- Примітиви повинні бути максимально швидкими та легкими.
Рішення виглядає трохи дивно, але так і є:
- Примітиви залишаються примітивами. Лише значення, як ви і хотіли.
- JavaScript дозволяє отримати доступ до методів та властивостей рядків, чисел, булеанів та символів.
- Для цього створюється спеціальний “об’єкт обгортка” з додатковою функціональністю, який потім знищується.
Для кожного примітиву створюється своя “обгортка”: String
, Number
, Boolean
, Symbol
та BigInt
. Отже, вони містять різні набори методів.
Наприклад: існує такий метод для рядка, як str.toUpperCase(), який поверне рядок str
з великими літерами.
Ось як він працює:
let str = "Привіт";
alert( str.toUpperCase() ); // ПРИВІТ
Не складно, так? Ось що саме трапляється в str.toUpperCase()
:
- Рядок
str
є примітивом. Тому під час звернення до його властивості створюється спеціальний об’єкт, який знає значення рядка і має корисні методи, такі якtoUpperCase()
. - Цей метод виконується і повертає новий рядок (що показує
alert
). - Спеціальний об’єкт руйнується, залишаючи лише примітив
str
.
Отже, примітиви можуть надавати методи, але залишаються “легкими”.
Двигун JavaScript добре оптимізує цей процес. Він навіть може пропустити створення додаткового об’єкта взагалі. Але він все ще повинен дотримуватися специфікації і вести себе так, наче він її створює.
Число має свої методи, наприклад: toFixed(n) – округлює число до заданої точності:
let n = 1.23456;
alert( n.toFixed(2) ); // 1.23
Ми переглянемо більш конкретні методи у розділах Числа та Рядки.
String/Number/Boolean
лише для внутрішнього використанняДеякі мови як Java дозволяють явно створювати “об’єкт обгортку” для примітивів, використовуючи синтаксис як new Number(1)
або new Boolean(false)
.
У JavaScript це також можливо з історичних причин, але надзвичайно не рекомендується. Це призведе до непередбачуваних речей.
Наприклад:
alert( typeof 0 ); // "number"
alert( typeof new Number(0) ); // "object"!
Об’єкти завжди повертають true
в if
, отже ми побачимо alert
:
let zero = new Number(0);
if (zero) { // zero є true, тому що це об’єкт
alert( "zero є true!?!" );
}
З іншого боку, використання тих же самих функцій String/Number/Boolean
без new
є абсолютно розумною і корисною річчю. Вони перетворюють значення у відповідний тип: рядок, число або булеве значення (примітиву).
Наприклад, це цілком правильно:
let num = Number("123"); // конвертує рядок в число
Винятки становлять спеціальні примітиви null
і undefined
. Вони не мають відповідних “об’єктів обгорток” і не надають ніяких методів. Ми можемо назвати їх “найпримітивнішими”.
Спроба доступу до властивості такого значення дасть помилку:
alert(null.test); // помилка
Підсумки
- Примітиви, крім
null
іundefined
, дають багато корисних методів. Ми вивчимо їх у наступних розділах. - Формально, ці методи працюють через тимчасові об’єкти, але двигун JavaScript оптимізовано для швидкого виконання цих операцій, тому нам не треба хвилюватися.