Пошук уроків, статей та іншого контенту
Дізнайтеся, що означає динамічна типізація та чому одна змінна в JavaScript може містити значення різних типів у різні моменти виконання програми.
У JavaScript тип належить не змінній, а значенню, яке зберігається у змінній.
Це означає, що одна й та сама змінна може спочатку містити число, потім рядок, а пізніше — логічне значення:
let value = 42;
console.log(value); // 42
value = "JavaScript";
console.log(value); // JavaScript
value = true;
console.log(value); // trueJavaScript визначає тип значення під час виконання програми. Саме тому типізацію JavaScript називають динамічною.
У мовах зі статичною типізацією тип змінної зазвичай задають заздалегідь і не можна довільно замінити значення іншим типом.
Наприклад, умовний код статично типізованої мови може виглядати так:
number age = 25;
age = "двадцять п'ять"; // помилка типівУ JavaScript тип змінної не фіксується під час її оголошення:
let age = 25;
age = "двадцять п'ять"; // допустимоЗмінна age спочатку посилалася на числове значення, а потім — на рядкове.
Динамічна типізація робить код гнучкішим, але вимагає уважності: помилки типів можуть проявитися лише під час виконання програми.
У JavaScript є примітивні типи та тип object.
До основних примітивних типів належать:
string — рядок;
number — число;
bigint — велике ціле число;
boolean — логічне значення true або false;
undefined — значення не визначене;
symbol — унікальний ідентифікатор;
null — спеціальне значення, що позначає відсутність об’єкта.
Окремо існує тип object, до якого належать об’єкти, масиви, функції та інші складні структури.
Для початку найчастіше використовуються string, number, boolean, undefined, null та object.
Змінна, оголошена за допомогою let, може отримувати нові значення різних типів:
let result = 10;
console.log(typeof result); // "number"
result = "Готово";
console.log(typeof result); // "string"
result = false;
console.log(typeof result); // "boolean"Оператор typeof повертає рядок із назвою типу значення.
let data = 100;
console.log(typeof data); // "number"
data = "100";
console.log(typeof data); // "string"
data = null;
console.log(typeof data); // "object"
data = undefined;
console.log(typeof data); // "undefined"Зверніть увагу: 100 і "100" — це різні значення. Перше є числом, друге — рядком.
let, const і динамічна типізаціяДинамічна типізація працює і з let, і з const, але ці ключові слова мають різні правила повторного присвоєння.
letЗмінній, оголошеній через let, можна присвоювати нові значення:
let userInput = 25;
userInput = "25";
userInput = true;
console.log(userInput); // trueconstЗмінній, оголошеній через const, не можна повторно присвоїти інше значення:
const language = "JavaScript";
// language = "Python"; // TypeErrorЦе не означає, що const має незмінний тип. Обмеження стосується самого присвоєння змінній нового значення.
Наприклад, об’єкт, оголошений через const, можна змінювати:
const user = {
name: "Олена"
};
user.name = "Андрій";
console.log(user.name); // АндрійТут змінюється властивість об’єкта, але змінна user продовжує посилатися на той самий об’єкт.
Під час виконання програми JavaScript перевіряє тип значення, яке зараз містить змінна:
let value = 5;
console.log(typeof value); // "number"
value = value > 0;
console.log(value); // true
console.log(typeof value); // "boolean"Вираз value > 0 повертає логічне значення. Тому після присвоєння тип value змінюється з number на boolean.
Розглянемо ще один приклад:
let message = "Привіт";
if (message.length > 0) {
message = 1;
}
console.log(message); // 1
console.log(typeof message); // "number"Спочатку message містить рядок, але всередині умови отримує число.
Функція в JavaScript також може отримувати аргументи різних типів:
function showValue(value) {
console.log(value);
console.log(typeof value);
}
showValue(42);
// 42
// "number"
showValue("42");
// "42"
// "string"
showValue(true);
// true
// "boolean"Функція showValue не вимагає, щоб параметр value завжди був певного типу.
Це зручно для універсальних функцій, але іноді може призвести до помилок. Якщо функція очікує число, краще перевірити тип аргументу або явно перетворити значення.
У наступній програмі змінна input отримує значення різних типів. Функція describeValue визначає поточний тип і виводить відповідне повідомлення.
function describeValue(value) {
const type = typeof value;
if (type === "number") {
console.log(`Це число: ${value}`);
} else if (type === "string") {
console.log(`Це рядок: ${value}`);
} else if (type === "boolean") {
console.log(`Це логічне значення: ${value}`);
} else if (value === null) {
console.log("Це значення null");
} else {
console.log(`Тип значення: ${type}`);
}
}
let input = 25;
describeValue(input);
input = "25";
describeValue(input);
input = false;
describeValue(input);
input = null;
describeValue(input);Результат:
Це число: 25
Це рядок: 25
Це логічне значення: false
Це значення nullОдна змінна input послідовно містила число, рядок, логічне значення та null.
JavaScript іноді автоматично перетворює значення одного типу на інший. Це називають неявним перетворенням типів.
Наприклад:
const number = 10;
const text = "5";
console.log(number + text); // "105"Якщо один операнд у виразі + є рядком, JavaScript перетворює число на рядок і об’єднує значення.
Для арифметичних операцій результат може бути іншим:
console.log("10" - 3); // 7
console.log("10" * 2); // 20Рядок "10" автоматично перетворюється на число.
Не покладайтеся на такі перетворення без необхідності. Явно перетворити значення зрозуміліше:
const text = "10";
const number = Number(text);
console.log(number + 5); // 15Для перевірки типу та порівняння зазвичай варто використовувати строге порівняння:
console.log(10 === "10"); // false
console.log(10 === 10); // trueОператор === порівнює і значення, і їхні типи.
typeof nullУ JavaScript вираз typeof null повертає "object":
console.log(typeof null); // "object"Це історична особливість JavaScript. null не є звичайним об’єктом, але результат typeof для нього саме такий.
Якщо потрібно перевірити, чи значення дорівнює null, використовуйте строге порівняння:
const value = null;
console.log(value === null); // trueJavaScript має типи, але вони визначаються під час виконання, а не обов’язково заздалегідь.
У цьому прикладі тип значення можна перевірити:
let item = "текст";
console.log(typeof item); // "string"Після цього значення може змінити тип:
item = 123;
console.log(typeof item); // "number"Отже, правильніше казати, що JavaScript — це мова з динамічною типізацією, а не мова без типів.
можна швидко створювати змінні без явного опису їхніх типів;
функції можуть працювати з різними типами даних;
код часто виходить коротшим і гнучкішим;
зручно працювати з даними, структура яких визначається під час виконання.
помилка типу може виникнути лише під час виконання;
неочікувані перетворення можуть спричинити неправильний результат;
великі програми складніше підтримувати без чітких правил роботи з типами;
потрібно уважно перевіряти дані, отримані від користувача або зовнішніх джерел.
const age = "20";
console.log(age + 1); // "201", а не 21age містить рядок, тому оператор + об’єднує значення.
Правильний варіант:
const age = "20";
const nextAge = Number(age) + 1;
console.log(nextAge); // 21typeof для перевірки nullconst value = null;
console.log(typeof value === "object"); // trueТакий результат може бути неочікуваним. Перевіряйте null окремо:
console.log(value === null); // true==Нестроге порівняння може виконувати автоматичне перетворення типів:
console.log(5 == "5"); // trueУ більшості випадків краще використовувати ===:
console.log(5 === "5"); // falseТакий код допустимий, але його складніше читати:
let data = 10;
data = "десять";
data = false;Якщо змінна має представляти різні сутності, краще використовувати окремі змінні з чіткими назвами:
const amount = 10;
const amountText = "десять";
const isAvailable = false;Дані з поля введення зазвичай отримують у вигляді рядка, навіть якщо користувач вводить число:
const input = "25";
console.log(typeof input); // "string"Перед обчисленнями таке значення потрібно перетворити:
const input = "25";
const price = Number(input);
console.log(price * 2); // 50JavaScript використовує динамічну типізацію.
Тип належить поточному значенню, а не самій змінній.
Змінна, оголошена через let, може містити значення різних типів у різні моменти виконання.
const забороняє повторне присвоєння, але не робить усі вкладені дані незмінними.
Оператор typeof допомагає перевірити тип значення.
typeof null повертає "object" — це особливість JavaScript.
Неявні перетворення типів можуть бути зручними, але часто спричиняють помилки.
Для передбачуваної поведінки використовуйте явне перетворення типів і строге порівняння ===.
Динамічна типізація не означає відсутність типів: типи є, просто вони визначаються під час виконання.