Пошук уроків, статей та іншого контенту
Дізнайтеся, у якому порядку JavaScript виконує оператори у складних виразах. Навчіться використовувати дужки, щоб явно задавати порядок обчислень і робити код зрозумілішим.
Пріоритет операторів визначає, у якому порядку JavaScript обчислює частини виразу.
Наприклад:
const result = 2 + 3 * 4;
console.log(result); // 14Спочатку виконується множення:
2 + (3 * 4) = 14Якби всі оператори виконувалися зліва направо без правил пріоритету, результат був би іншим:
(2 + 3) * 4 = 20Пріоритет потрібен, щоб JavaScript міг однозначно інтерпретувати складні вирази.
Оператори з вищим пріоритетом виконуються раніше за оператори з нижчим пріоритетом.
Наприклад:
const value = 10 + 2 * 3 ** 2;
console.log(value); // 28Порядок обчислення:
3 ** 2 = 9
2 * 9 = 18
10 + 18 = 28Дужки мають найвищий практичний пріоритет і дозволяють змінити порядок:
const value = (10 + 2) * 3 ** 2;
console.log(value); // 108Тепер спочатку виконується вираз у дужках:
(10 + 2) * 9 = 108Дужки використовують не лише для зміни результату. Вони також роблять намір програміста зрозумілим.
Порівняйте:
const total = price * quantity + delivery;І:
const total = (price * quantity) + delivery;У цьому прикладі результат однаковий, але другий варіант одразу показує логіку обчислення: спочатку вартість товарів, потім додавання доставки.
Дужки особливо корисні у складних умовах:
const canAccess = (isLoggedIn && isAdmin) || isOwner;Без дужок JavaScript також правильно обчислить цей вираз, оскільки && має вищий пріоритет, ніж ||. Проте дужки спрощують читання коду.
Повну специфікацію пріоритетів не обов’язково запам’ятовувати. Для повсякденної роботи найчастіше потрібен такий порядок — від вищого до нижчого:
Дужки та доступ до властивостей:
(expression)
object.property
object[property]
function()
object?.property
Унарні оператори:
!value
typeof value
++value
value++
-value
Піднесення до степеня:
**
Множення, ділення та залишок:
*
/
%
Додавання та віднімання:
+
-
Порівняння:
<, >, <=, >=
in
instanceof
Рівність:
==, !=
===, !==
Логічне НЕ:
! — фактично унарний оператор, тому має вищий пріоритет за інші логічні оператори
Логічне І:
&&
Логічне АБО:
||
Оператор нульового злиття:
??
Умовний оператор:
condition ? valueIfTrue : valueIfFalse
Оператори присвоєння:
=
+=
-=
*=
Кома:
,
Є нюанс: ! має вищий пріоритет за &&, а && — вищий за ||.
const result = !false && false || true;
console.log(result); // trueПорядок:
(!false) && false || true
true && false || true
false || true
trueСпочатку виконуються *, /, %, а потім + і -.
const first = 20 - 6 / 2;
const second = (20 - 6) / 2;
console.log(first); // 17
console.log(second); // 7У першому виразі:
20 - (6 / 2) = 17У другому виразі дужки змінюють порядок:
(20 - 6) / 2 = 7Оператор % повертає залишок від ділення:
const result = 17 + 10 % 4 * 2;
console.log(result); // 21Порядок:
10 % 4 = 2
2 * 2 = 4
17 + 4 = 21Оператор + використовується і для додавання чисел, і для об’єднання рядків. Якщо одним з операндів є рядок, результатом часто стає рядок.
const result = "Сума: " + 10 + 5;
console.log(result); // "Сума: 105"Обчислення відбувається зліва направо:
("Сума: " + 10) + 5
"Сума: 10" + 5
"Сума: 105"Якщо потрібно спочатку додати числа, використовуйте дужки:
const result = "Сума: " + (10 + 5);
console.log(result); // "Сума: 15"Це одна з найпоширеніших ситуацій, коли дужки впливають не лише на читабельність, а й на тип результату.
Оператор ** має вищий пріоритет, ніж множення, ділення, додавання та віднімання:
const result = 2 + 3 * 2 ** 2;
console.log(result); // 14Порядок:
2 ** 2 = 4
3 * 4 = 12
2 + 12 = 14Оператор ** є правоасоціативним. Це означає, що вираз обчислюється справа наліво:
const result = 2 ** 3 ** 2;
console.log(result); // 512JavaScript читає його так:
2 ** (3 ** 2)А не так:
(2 ** 3) ** 2Для від’ємного числа перед степенем потрібні дужки:
const first = (-2) ** 2;
const second = -(2 ** 2);
console.log(first); // 4
console.log(second); // -4Вираз -2 ** 2 є синтаксично некоректним у JavaScript. Потрібно явно вказати бажаний порядок за допомогою дужок.
Арифметичні операції виконуються раніше за порівняння:
const isLarge = 10 + 5 > 12;
console.log(isLarge); // trueJavaScript спочатку обчислює 10 + 5, а потім порівнює результат із 12:
15 > 12Оператори рівності мають нижчий пріоритет, ніж оператори порівняння:
const result = 5 < 10 === true;
console.log(result); // trueПорядок:
(5 < 10) === true
true === true
trueДля порівняння без неочікуваного перетворення типів зазвичай використовують строгі оператори:
const age = 18;
const isAdult = age >= 18;
const hasExactAge = age === 18;
console.log(isAdult); // true
console.log(hasExactAge); // trueЛогічні оператори мають такий порядок пріоритету:
!
&&
||Отже, цей вираз:
const result = a || b && c;еквівалентний такому:
const result = a || (b && c);Оператор && виконується раніше за ||.
Оператор ! змінює логічне значення на протилежне:
const isBlocked = false;
const canEnter = !isBlocked;
console.log(canEnter); // trueУ складних виразах ! застосовується до найближчого операнда:
const result = !isReady && hasPermission;
console.log(result);Цей вираз означає:
const result = (!isReady) && hasPermission;Якщо потрібно заперечити весь складний вираз, використовуйте дужки:
const result = !(isReady && hasPermission);Оператор && повертає перше хибне значення або останнє значення, якщо всі операнди істинні.
const username = "olena";
const password = "secret";
const message = username && password && "Дані заповнені";
console.log(message); // "Дані заповнені"Оператор && використовує коротке замикання: якщо вже знайдено хибне значення, наступні операнди не обчислюються.
const user = null;
const name = user && user.name;
console.log(name); // nullВластивість name не читається, оскільки user дорівнює null.
Оператор || повертає перше істинне значення або останнє значення, якщо всі операнди хибні.
const inputName = "";
const name = inputName || "Гість";
console.log(name); // "Гість"Цей підхід корисний для значень за замовчуванням, але він вважає хибними всі такі значення:
false
0
""
null
undefined
NaNЯкщо потрібно перевіряти лише null або undefined, використовуйте ??.
??Оператор ?? повертає праве значення лише тоді, коли ліве дорівнює null або undefined.
const count = 0;
const withOr = count || 10;
const withNullish = count ?? 10;
console.log(withOr); // 10
console.log(withNullish); // 00 є хибним значенням для ||, але не є null або undefined, тому ?? зберігає його.
Важливе правило: не можна безпосередньо змішувати ?? з || або && без дужок.
Некоректний код:
// Синтаксична помилка
const value = first ?? second || third;Потрібно явно вказати порядок:
const value = (first ?? second) || third;Або:
const value = first ?? (second || third);Це правило захищає від неочевидної логіки у складних умовах.
Тернарний оператор має три частини:
condition ? valueIfTrue : valueIfFalseНаприклад:
const age = 20;
const status = age >= 18 ? "дорослий" : "неповнолітній";
console.log(status); // "дорослий"Оператори порівняння виконуються раніше за ? :, тому дужки тут необов’язкові:
const status = (age >= 18) ? "дорослий" : "неповнолітній";У складніших виразах краще використовувати дужки або звичайний if, щоб не створювати важкі для читання конструкції.
const score = 82;
const hasCertificate = true;
const result =
score >= 90
? "відмінно"
: score >= 60 && hasCertificate
? "зараховано"
: "потрібне доопрацювання";
console.log(result); // "зараховано"Такий вкладений тернарний оператор працює, але його може бути складно підтримувати. Часто зрозумілішим буде if...else.
Оператори присвоєння мають нижчий пріоритет, ніж більшість інших операторів.
let total;
total = 10 + 5 * 2;
console.log(total); // 20Спочатку обчислюється права частина:
10 + (5 * 2)Потім результат присвоюється змінній total.
Складені оператори також враховують обчислений вираз:
let score = 10;
score += 5 * 2;
console.log(score); // 20Це еквівалентно:
score = score + (5 * 2);Ланцюжок присвоєнь виконується справа наліво:
let first;
let second;
let third;
first = second = third = 0;
console.log(first, second, third); // 0 0 0Спочатку значення 0 присвоюється third, потім це саме значення — second, а потім — first.
Пріоритет визначає, яку операцію виконати першою, але не завжди означає, що JavaScript фізично обчислює всі частини саме в такому напрямку.
Операнди зазвичай обчислюються зліва направо. Це важливо, якщо під час обчислення є побічні ефекти:
let value = 0;
function getValue() {
value += 1;
return value;
}
const result = getValue() + getValue() * 10;
console.log(result); // 21
console.log(value); // 2Спочатку викликається ліва функція:
getValue() повертає 1Потім права:
getValue() повертає 2Після цього застосовується пріоритет множення:
1 + (2 * 10) = 21Не варто покладатися на складні побічні ефекти в одному виразі. Краще розділяти обчислення на окремі інструкції.
Якщо кілька операторів мають однаковий пріоритет, порядок їхнього групування визначається асоціативністю.
Більшість арифметичних операторів є лівоасоціативними:
const result = 20 / 5 * 2;
console.log(result); // 8Вираз групується зліва направо:
(20 / 5) * 2Для віднімання це особливо помітно:
const result = 20 - 5 - 3;
console.log(result); // 12Порядок:
(20 - 5) - 3 = 12Не:
20 - (5 - 3) = 18Оператор ** є правоасоціативним:
const result = 2 ** 3 ** 2;
console.log(result); // 512Групування:
2 ** (3 ** 2)А оператори присвоєння також групуються справа наліво:
let a;
let b;
a = b = 10;Розглянемо обчислення вартості замовлення:
const price = 250;
const quantity = 3;
const discountPercent = 10;
const deliveryPrice = 80;
const isFreeDelivery = false;
const subtotal = price * quantity;
const discount = subtotal * (discountPercent / 100);
const totalBeforeDelivery = subtotal - discount;
const delivery = isFreeDelivery ? 0 : deliveryPrice;
const total = totalBeforeDelivery + delivery;
console.log(`До знижки: ${subtotal} грн`);
console.log(`Знижка: ${discount} грн`);
console.log(`Доставка: ${delivery} грн`);
console.log(`Разом: ${total} грн`);Результат:
До знижки: 750 грн
Знижка: 75 грн
Доставка: 80 грн
Разом: 755 грнЦей приклад можна записати одним виразом, але такий код буде складнішим для перевірки:
const total =
price * quantity -
price * quantity * (discountPercent / 100) +
(isFreeDelivery ? 0 : deliveryPrice);Використання проміжних змінних часто краще за надмірно складний вираз. Воно:
спрощує відлагодження;
робить кожен етап зрозумілим;
зменшує ризик помилки у дужках;
полегшує повторне використання проміжних результатів.
Під час роботи зі складними виразами дотримуйтеся таких правил:
Використовуйте дужки, якщо порядок обчислення може бути неочевидним.
Не намагайтеся запам’ятати весь список пріоритетів.
Розділяйте довгі обчислення на проміжні змінні.
Не змішуйте без потреби арифметику, порівняння та логіку в одному рядку.
Пам’ятайте про різницю між || і ??.
Звертайте увагу на асоціативність -, /, ** і присвоєння.
Пам’ятайте, що + може додавати числа або об’єднувати рядки.
Для складних умов використовуйте if, коли тернарний оператор стає важким для читання.
const result = 2 + 3 * 4;
console.log(result); // 14, а не 20Якщо потрібен інший порядок, додайте дужки:
const result = (2 + 3) * 4;
console.log(result); // 20const result = "Всього: " + 2 + 3;
console.log(result); // "Всього: 23"Правильний варіант:
const result = "Всього: " + (2 + 3);
console.log(result); // "Всього: 5"|| замість ??const page = 0;
console.log(page || 1); // 1
console.log(page ?? 1); // 0Якщо 0 є коректним значенням, ?? краще відповідає потребі.
const isLoggedIn = true;
const isAdmin = false;
const isOwner = true;
const canEdit = isLoggedIn && isAdmin || isOwner;
console.log(canEdit); // trueJavaScript читає вираз так:
const canEdit = (isLoggedIn && isAdmin) || isOwner;Якщо доступ мають отримувати лише авторизовані користувачі, а серед них — адміністратори або власники, умову потрібно записати так:
const canEdit = isLoggedIn && (isAdmin || isOwner);
console.log(canEdit); // trueДужки тут виражають бізнес-правило, а не лише змінюють технічний порядок операцій.
const result = 100 - 20 - 10;
console.log(result); // 70Операції виконуються зліва направо:
(100 - 20) - 10Якщо потрібен інший результат:
const result = 100 - (20 - 10);
console.log(result); // 90const result = 2 ** 3 ** 2;
console.log(result); // 512Вираз групується справа наліво:
2 ** (3 ** 2)Для явності краще додати дужки навіть тоді, коли ви знаєте правило.
?? і || без дужок// Синтаксична помилка
const value = null ?? false || true;Правильний варіант:
const value = (null ?? false) || true;
console.log(value); // trueПріоритет операторів визначає порядок виконання частин виразу.
Дужки мають найвищий пріоритет і дозволяють явно задати порядок обчислень.
Множення, ділення та залишок виконуються раніше за додавання й віднімання.
Порівняння виконуються раніше за логічні оператори.
Логічні оператори мають порядок !, потім &&, потім ||.
?? відрізняється від ||: він реагує лише на null і undefined.
+ може виконувати арифметичне додавання або об’єднання рядків.
Більшість операторів групуються зліва направо, але ** і присвоєння — справа наліво.
Довгі вирази краще розділяти на проміжні змінні.
Дужки варто використовувати не лише для зміни результату, а й для підвищення зрозумілості коду.