Розуміння типів даних JavaScript — це основа, на якій будується робота будь-якого розробника: від першої програми «Hello, world!» до створення складних інтерфейсних програм. Всі операції: порівняння, обчислення, робота зі сховищами та налаштування інтерфейсів, так чи інакше спираються на знання типів даних та розуміння їх особливостей.
Ця стаття призначена для новачків у JavaScript. Ми розберемо, які типи даних підтримує мова, в чому між ними різниця, і як правильно їх використовувати на практиці. Прочитавши статтю ви будете вільно визначати типи даних, пояснювати різницю між примітивами та об'єктами, а також уникати типових помилок, пов'язаних із копіюванням та зберіганням значень.
Рекомендації щодо вивчення теми
Для поглибленого вивчення теми рекомендую такі джерела, які використовувалися для підготовки даної статті
- Ви не знаєте JS: Типи та граматика
- Для кого: читається легко і новачками, і тим, хто щось знає.
- Що всерединуі: сучасне та докладне пояснення підводних каменів роботи з типами з прикладами «з реального життя».
- ECMAScript Data Types and Values
- Для кого: тим, хто хоче точності та не боїться англійської технічної документації.
- Що всередині: офіційний стандарт, максимально коректно описані всі нюанси внутрішньої реалізації типів даних JavaScript.
- ECMAScript Overview
- Для кого: для тих, хто не боїться специфікацій
- Що всередині: огляд усієї архітектури стандарту ECMAScript, включаючи класифікацію даних.
Як JavaScript зберігає дані: примітиви та об'єкти
На момент написання статті стандарт ECMAScript підтримує 8 типів даних. З них 7 примітивних і лише 1 об'єктний, тобто складовий.
Що таке тип даних і навіщо це знати?
Тип даних визначає, що вміє робити конкретна змінна: чи можна її скласти з іншим числом, перевірити, чи порожній рядок, перебрати елементи або викликати як функцію. Фізично значення зберігаються по-різному, і це впливає на поведінку нашого коду при копіюванні змінних та роботі з пам'яттю.
Всі типи даних у JavaScript
- Undefined - тип з єдиним значенням
undefined. Зазвичай означає значення не встановлено. - Null — спеціальне «нічого», але вже явно надане змінній. Часто використовується для очищення вмісту.
- Boolean - логічні значення:
trueіfalse. - Number — усі числа: цілі та дробові, включаючи
NaN,Infinity. - BigInt - великі цілі числа (що вийшли за межі типового
Number- 2 ^ 53-1). - String - рядки, будь-які послідовності символів.
- Symbol - унікальний і незмінний ідентифікатор. Найчастіше використовується як ключі в об'єктах.
- Object - універсальний «контейнер», може зберігати будь-які колекції, складні структури, масиви, функції.
Чому важливо розрізняти примітиви та об'єкти?
Примітив (undefined, null, boolean, number, bigint, string, symbol) зберігається «за значенням»: присвоюючи одну змінну інший, ви копіюєте саме значення.
Об'єкти ж зберігаються «за посиланням»: при присвоєнні копіюється не сам об'єкт, а лише його «покажчик» на область пам'яті, де знаходиться об'єкт.
Приклад:
let a = 1;
let b = a; // b — this is a new primitive: if a changes, b will not change.
let obj1 = {x: 10};
let obj2 = obj1; // obj2 — this is a reference to the same object. By changing obj2.x, you will also change obj1.x.
Ця різниця часто стає причиною плутанини у новачків. Слідкуйте, коли копіюєте об'єкти - ви працюєте з однією і тією ж сутністю у пам'яті!
Як визначити тип значення у вашому коді: оператор typeof
Оператор typeof допомагає в розробці та налагодженні: він повертає рядок, що відповідає типу значення.
Приклади:
typeof undefined // "undefined"
typeof true // "boolean"
typeof "42" // "string"
typeof 42 // "number"
typeof BigInt("9007199254740991") // "bigint"
typeof Symbol() // "symbol"
typeof {a: 1} // "object"
typeof function(){} // "function"
Важливо
Для null результат неочевидний: typeof null // "object". Це історична помилка стандарту, її треба знати.
Для масивів та функцій typeof повертає "object" і "function" відповідно, хоча обидва є підтипами об'єкта.
Декілька слів про кожен тип: що важливо пам'ятати на практиці
Undefined
Найчастіше отримуєте цей тип, якщо оголосили змінну, але не надали їй значення:
let a;
console.log(a); // undefined
console.log(typeof a) // "undefined"
Boolean
Базовий інструмент для перевірки умов:
let isAdult = age > 18; // true or false
Number та BigInt
Number охоплює більшість потреб, але його точності не вистачить для дуже великих цілих чисел. Для роботи з великими числами використовуйте BigIntнаприклад, при обчисленнях з великими рахунками.
String
Для зберігання та обробки текстів - імена, описи, адреси і т.д.
Symbol
Використовується рідко, частіше для створення унікальних ключів в об'єктах чи бібліотечних абстракціях.
Null
Усвідомлена відсутність значення. Новачки часто плутають його з undefined. Головна відмінність: undefined - «значення ще не було встановлено», а null - Значення явно відсутнє (скинуто).
Object (і його підтипи)
Об'єкти це асоціативні контейнери
Найчастіше вони створюються за допомогою літералу об'єктів (фігурні дужки). Ключами в об'єктах є рядки або символи, а значеннями будь-які типи.
let user = {
firstName: 'John',
lastName: 'Doe',
phone: '555-24-42'
};
console.log(user.firstName); // "John"
console.log(user['firstName']); // "John"
Функції – особливий вид об'єкту
Однією з ключових особливостей функцій є перевикористання коду. Ідея полягає в тому, що ми виносимо в них код, який необхідно виконати кілька разів у програмі, і викликаємо цю функцію там, де це необхідно.
Одним із способів створення функції є оголошення за допомогою ключового слова function, після якого йде ім'я функції. Тіло функції визначається у фігурних дужках. Викликати функцію можна за її ім'ям, після чого йдуть круглі дужки.
Функції є підтипом об'єкта і називаються об'єктом, що викликається (callable object). Познайомившись із функціями ближче, можна помітити, що з ними справді можна поводитися, як з об'єктами. Наприклад, у них є властивість «length», до якої можна звернутися через крапку після імені змінної, як ми робили це в об'єкті. Ця властивість говорить про кількість аргументів функції (передані дані). У нашому прикладі повернеться нуль.
function greet() { /* code */ }
console.log(typeof greet); // "function" (callable object)
console.log(greet.length); // 0
Масиви - впорядковані колекції
Масив, як і функція є підтипом об'єкта. Масиви також використовуються як сховище даних і можуть зберігати елементи різних типів, навіть інші масиви. У прикладі нижче ми оголосили масив за допомогою літералу масиву (квадратні дужки після знака дорівнює) і відразу ж визначили в ньому три елементи: число, рядок та інший масив.
let arr = [1, "2", [3]];
console.log(arr[0]); // 1
console.log(arr[2]); // [3]
Кожному елементу, збереженому в масив, присвоюється індекс (його номер за порядком, починаючи з нуля). Надалі елемент масиву може бути отриманий за цим індексом. У нашому прикладі ми запитуємо перший елемент масиву. Для цього використовуємо квадратні дужки після імені змінної, в які передаємо необхідний індекс, тобто нуль.
Масиви використовуються для будь-яких колекцій, де важливим є порядок елементів (наприклад, черга користувачів):
let userQueue = [
{fullName: 'John Doe'},
{fullName: 'Martha Stuart'},
{fullName: 'Sam Sparks'}
];
let firstUserInQueue = userQueue[0];
console.log(firstUserInQueue.fullName); // "John Doe"
Кілька нескладних вправ щодо збереження різних типів даних у змінні для закріплення вивченого матеріалу:
- Надайте значення 7 змінній “a”.
- Надайте вміст “a” змінній “b”.
- Визначте змінну “a” за допомогою var та ініціалізуйте її значенням 9.
- Ініціалізуйте три змінні “a”, “b” та “c” значеннями 5, 10 та “I am a” відповідно, щоб вони не були невизначеними.
- Змініть існуючі оголошення та присвоєння так, щоб у їхніх іменах використовувався camelCase. Не створюйте нових змінних.
Типові помилки та коментарі
- Копіювання об'єктів. При виконанні
let b = a(якщоaіb- об'єкти) ви копіюєте не сам об'єкт, а посилання на нього. Щоб скопіювати об'єкт за значенням, використовуйте, наприклад,Object.assign({}, obj)або spread-оператор{...obj}. - typeof null. Повертає "object", хоча сам
null- Це не об'єкт. Просто запам'ятайте цю особливість, інакше можна помилитися під час перевірки значень. - Перевірка масиву.
typeof arrдля масиву повертає "object", а не "array". Для точної перевірки використовуйтеArray.isArray(arr).
Короткий підсумок: запам'ятати та застосовувати
- У JS існує 7 примітивних типів даних та один об'єктний, з якого «виростають» функції та масиви.
- Головна відмінність: примітиви копіюються за значенням, об'єкти - за посиланням.
- Для перевірки типу використовуйте оператор
typeof, але пам'ятайте винятки (особливо зnullта масивами). - Типи даних не абстракція, а щоденний інструмент: від вибору правильного типу залежить поведінка коду та його надійність.
- Напрацюйте звичку розрізняти та правильно використовувати типи: це основа роботи зі змінними та об'єктами у будь-якому проекті.

