Операторы работы с битами

Операторы работы с битами выполняют операции на уровне отдельных битов целочисленных значений. В мобильной разработке они встречаются редко, но могут быть полезны при оптимизации хранения флагов, работе с сетевыми протоколами, обработке изображений или взаимодействии с нативными модулями.


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

Все битовые операции в JavaScript работают с 32-битными целыми числами. Любые числа перед операцией приводятся к этому формату (дробные части отбрасываются).

Оператор Название Описание
& Побитовое И В каждом бите результат = 1, только если оба операнда имеют 1
| Побитовое ИЛИ В каждом бите результат = 1, если хотя бы один операнд имеет 1
^ Побитовое исключающее ИЛИ (XOR) В каждом бите результат = 1, если биты разные
~ Побитовое НЕ (инверсия) Инвертирует все биты (0 → 1, 1 → 0)
<< Сдвиг влево Сдвигает биты влево на указанное количество, заполняя справа нулями
>> Арифметический сдвиг вправо Сдвигает биты вправо, сохраняя знаковый бит (для отрицательных чисел)
>>> Логический сдвиг вправо Сдвигает биты вправо, заполняя слева нулями (игнорирует знак)

Примеры использования

Побитовое И (&) — проверка флагов

Часто используется для хранения нескольких булевых состояний в одном числе.

const READ = 1;    // 0001
const WRITE = 2;   // 0010
const EXEC = 4;    // 0100
const DELETE = 8;  // 1000

let permissions = READ | WRITE | EXEC; // 0111 = 7

// Проверяем, есть ли право на чтение:
if (permissions & READ) {
  console.log("Можно читать"); // выполнится
}

// Проверяем, есть ли право на удаление:
if (permissions & DELETE) {
  console.log("Можно удалять"); // не выполнится
}

✅ Экономит память и ускоряет проверки в низкоуровневых сценариях — например, при передаче прав доступа через API или хранении настроек в локальном хранилище.


Побитовое ИЛИ (|) — установка флагов

Объединяет несколько флагов в одно значение:

let flags = 0;
flags |= READ;   // 0001
flags |= WRITE;  // 0011
flags |= EXEC;   // 0111

console.log(flags); // 7

Побитовое исключающее ИЛИ (^) — переключение флага

Используется для инвертирования конкретного флага:

let theme = 0; // 0 — светлая, 1 — тёмная
theme ^= 1; // теперь theme = 1
theme ^= 1; // теперь theme = 0

Также применяется в алгоритмах шифрования или генерации контрольных сумм.


Побитовое НЕ (~) — инверсия битов

Применяется для преобразования чисел и часто встречается в сочетании с indexOf:

const arr = ["apple", "banana", "cherry"];
const index = arr.indexOf("banana");

if (~index) { // эквивалентно: if (index !== -1)
  console.log("Найдено");
}

❗ Устаревший стиль. Современный код предпочтительно пишет так:
if (index !== -1) — более читаемо и понятно.


Сдвиг влево (<<) — умножение на степени двойки

console.log(5 << 1); // 10 → 5 * 2¹
console.log(5 << 2); // 20 → 5 * 2²
console.log(1 << 3); // 8 → 2³

⚠️ Работает только с целыми числами. Не заменяет Math.pow() для дробных степеней.

Полезно при оптимизации вычислений в играх, графических движках или обработке сигналов.


Арифметический сдвиг вправо (>>) — деление на степени двойки (со знаком)

console.log(8 >> 1);  // 4 → 8 / 2
console.log(-8 >> 1); // -4 — знак сохранён

Сохраняет знак числа — подходит для целочисленного деления на 2, 4, 8 и т.д.


Логический сдвиг вправо (>>>) — деление на степени двойки (без знака)

Преобразует отрицательные числа в большие положительные:

console.log(-8 >>> 1); // 2147483644 — интерпретируется как беззнаковое число

Используется редко — в основном при работе с бинарными данными (например, Uint32Array, WebAssembly).


Где это может пригодиться в мобильной разработке?

  • Хранение флагов в одной переменной: например, права пользователя, состояние UI-элемента, режимы приложения.
  • Оптимизация производительности: в низкоуровневых системах (игры, аудио/видео обработка).
  • Работа с нативными модулями: когда приложение использует JNI (Android) или Objective-C/Swift-код, где данные передаются как битовые маски.
  • Компрессия данных: при отправке маленьких наборов булевых значений через API.