Операторы

Операторы — символы и ключевые слова, выполняющие действия над операндами: арифметика, сравнение, логика, присваивание.

Зачем нужно

Операторы — базовые строительные блоки выражений. Без них невозможны вычисления, сравнения и принятие решений.

Где используется

Буквально везде: математика, условия, присваивание, работа с битами, проверки типов.

Предпосылки

Переменные, Типы данных

Арифметические операторы

// Базовые
5 + 3;   // 8 (сложение)
5 - 3;   // 2 (вычитание)
5 * 3;   // 15 (умножение)
5 / 3;   // 1.6666... (деление)
5 % 3;   // 2 (остаток от деления)
5 ** 3;  // 125 (возведение в степень)

// Унарные
let x = 5;
-x;   // -5 (унарный минус)
+x;   // 5 (унарный плюс — преобразование в число)
+'42'; // 42

// Инкремент и декремент
let a = 5;
a++;  // 5 (вернул, потом увеличил) → a = 6
++a;  // 7 (увеличил, потом вернул)
a--;  // 7 (вернул, потом уменьшил) → a = 6
--a;  // 5 (уменьшил, потом вернул)

// Конкатенация строк через +
'Hello' + ' ' + 'World'; // 'Hello World'
'Цена: ' + 100;           // 'Цена: 100' (число → строка)

Операторы сравнения

// Строгое (рекомендуется)
5 === 5;     // true
5 === '5';   // false (разные типы)
null === undefined; // false

// Нестрогое (с приведением типов — избегай)
5 == '5';    // true
null == undefined; // true
0 == false;  // true
'' == false; // true

// Не равно
5 !== 3;     // true (строгое)
5 != '5';    // false (нестрогое)

// Больше/меньше
5 > 3;       // true
5 >= 5;      // true
3 < 5;       // true
3 <= 3;      // true

// Сравнение строк (по Unicode)
'a' < 'b';   // true
'Z' < 'a';   // true (заглавные < строчных)

// Object.is — ещё строже
Object.is(NaN, NaN);   // true (=== даёт false)
Object.is(0, -0);      // false (=== даёт true)

Логические операторы

// && (И) — возвращает первый falsy или последний
true && true;    // true
true && false;   // false
'hello' && 42;   // 42
'' && 42;        // ''

// || (ИЛИ) — возвращает первый truthy или последний
false || true;   // true
'' || 'default'; // 'default'
0 || 42;         // 42

// ! (НЕ) — инвертирует
!true;   // false
!0;      // true
!!'hello'; // true (двойное отрицание = boolean)

// ?? (Nullish coalescing)
null ?? 'default';      // 'default'
undefined ?? 'default'; // 'default'
0 ?? 'default';         // 0
'' ?? 'default';        // ''

Операторы присваивания

let x = 10;

x += 5;   // x = x + 5  → 15
x -= 3;   // x = x - 3  → 12
x *= 2;   // x = x * 2  → 24
x /= 4;   // x = x / 4  → 6
x %= 4;   // x = x % 4  → 2
x **= 3;  // x = x ** 3 → 8

// Логические присваивания (ES2021)
let a = null;
a ??= 'default';  // a = a ?? 'default' → 'default'

let b = '';
b ||= 'fallback'; // b = b || 'fallback' → 'fallback'

let c = 1;
c &&= 2;          // c = c && 2 → 2

// Деструктурирующее присваивание
let [first, second] = [1, 2];
let { name, age } = { name: 'Алиса', age: 25 };

Optional chaining (?.)

const user = {
  name: 'Алиса',
  address: { city: 'Москва' }
};

// Свойства
user?.address?.city;    // 'Москва'
user?.contacts?.email;  // undefined (не TypeError)

// Методы
user.getName?.;       // undefined если метода нет

// Скобочная нотация
const key = 'address';
user?.[key]?.city;      // 'Москва'

// Массивы
const arr = null;
arr?.[0];               // undefined (не TypeError)

Побитовые операторы

// Работают с 32-битными целыми числами
5 & 3;    // 1   (AND: 101 & 011 = 001)
5 | 3;    // 7   (OR:  101 | 011 = 111)
5 ^ 3;    // 6   (XOR: 101 ^ 011 = 110)
~5;       // -6  (NOT: инвертирует все биты)

// Сдвиги
8 >> 1;   // 4  (8 = 1000, сдвиг вправо → 0100 = 4)
2 << 3;   // 16 (2 = 10, сдвиг влево → 10000 = 16)

// Практическое применение
// Быстрое округление вниз
~~3.7;       // 3
3.7 | 0;     // 3
3.7 >> 0;    // 3

// Проверка чётности
7 & 1;       // 1 (нечётное)
8 & 1;       // 0 (чётное)

// Работа с флагами
const READ = 1;    // 001
const WRITE = 2;   // 010
const EXEC = 4;    // 100
let perms = READ | WRITE; // 011 = 3
(perms & READ) !== 0;     // true — есть право на чтение

Другие операторы

// typeof
typeof 42;          // "number"
typeof 'hello';     // "string"
typeof undefined;   // "undefined"

// instanceof
 instanceof Array;  // true
{} instanceof Object; // true (в консоли обернуть в скобки)

// in — проверка свойства
'name' in { name: 'Алиса' }; // true
0 in ['a', 'b'];              // true (индекс)

// delete — удаление свойства
const obj = { a: 1, b: 2 };
delete obj.a; // true, obj = { b: 2 }

// Тернарный
const status = age >= 18 ? 'взрослый' : 'несовершеннолетний';

// Запятая
const result = (1 + 2, 3 + 4); // 7 (возвращает последнее)

// void
void 0; // undefined

Приоритет операторов

Высший → Низший:
              — группировка
!  ~  ++  --    — унарные
**              — степень
*  /  %         — умножение/деление
+  -            — сложение/вычитание
<<  >>  >>>     — побитовые сдвиги
<  <=  >  >=    — сравнение
==  !=  ===  !== — равенство
&               — побитовое И
^               — побитовое XOR
|               — побитовое ИЛИ
&&              — логическое И
||              — логическое ИЛИ
??              — nullish coalescing
?:              — тернарный
=  +=  -=  ...  — присваивание
,               — запятая

Частые ошибки

1. Приоритет: || vs ?? с &&

// Нельзя смешивать без скобок
// a || b ?? c; // SyntaxError
(a || b) ?? c;  // OK
a || (b ?? c);  // OK

2. Сравнение с NaN

NaN === NaN; // false!
Number.isNaN(value); // правильная проверка

3. + со строками и числами

'5' + 3;   // '53' (конкатенация)
'5' - 3;   // 2 (вычитание — преобразование в число)

Практика

  1. Используй побитовые операторы для работы с правами доступа
  2. Напиши выражение, которое безопасно получает глубоко вложенное свойство
  3. Покажи разницу между ||, ?? и && для значений 0, '', null

Связанные темы

Ресурсы