
Короткие заметки о JavaScript и маленькие программки.
20 сентября 2025

В прошлой заметке мы показали XOR‑обмен на примере и таблице. Демонстрация — это не доказательство. Ниже — краткое строгое объяснение, почему XOR‑обмен работает.
Думайте о a ^ b как о переключении (инвертировании) битов a в тех позициях, где у b стоят 1. Дважды инвертируем — получаем исходное: a ^ b ^ b = a.
// Пусть исходные значения — a0 и b0 let a = a0, b = b0 a = a ^ b // a = a0 ^ b0, b = b0 b = a ^ b // a = a0 ^ b0, b = b0 ^ (a0 ^ b0) = a0 a = a ^ b // a = a0 ^ b0 ^ a0 = b0, b = a0
Результат общий: значения меняются местами без временной переменной для любых целых a0 и b0.
20 сентября 2025

В одной из заметок мы использовали оператор XOR для обмена значениями. После короткого введения в двоичную систему разберём XOR подробнее.
У операции несколько обозначений: ⊕, ^, xor. На одиночных битах она ведёт себя как «сумма по модулю 2»: 0, если входы равны, и 1, если различны. См. Википедию.
Побитовый XOR — это применение XOR к соответствующим битам двух двоичных чисел. Пример: 5 ^ 3. В двоичном виде: 101 ^ 011. По столбцам: 1^0=1, 0^1=1, 1^1=0 → 110 (то есть 6). Попробуйте: console.log(5 ^ 3).
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 1 | 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 |
| 2 | 2 | 3 | 0 | 1 | 6 | 7 | 4 | 5 |
| 3 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 |
| 4 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 |
| 5 | 5 | 4 | 7 | 6 | 1 | 0 | 3 | 2 |
| 6 | 6 | 7 | 4 | 5 | 2 | 3 | 0 | 1 |
| 7 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Проверим классический алгоритм обмена через XOR по этой таблице. Пусть a = 5, b = 4. Проследим значения после присваиваний:
a = a ^ b // a = 5 ^ 4 = 1, b = 4 b = a ^ b // a = 1, b = 1 ^ 4 = 5 a = a ^ b // a = 1 ^ 5 = 4, b = 5
15 сентября 2025

В одной из предыдущих заметок мы разбирали решение задачи «обменять два значения тремя переменными» с использованием оператора XOR. Здесь сделаем шаг назад и объясним, что происходит. Подробности о позиционной системе счисления по основанию 2 см. в Википедии. Главное:
Чтобы перевести двоичное число в десятичное, суммируем биты с весами (справа налево): 1, 2, 4, 8, 16, …. Примеры: 101 = 1×4 + 0×2 + 1×1 = 5; 011 = 0×4 + 1×2 + 1×1 = 3.
Для трёхбитных чисел: 000 → 0
001 → 1
010 → 2
011 → 3
100 → 4
101 → 5
110 → 6
111 → 7. Чтобы перевести из десятичного в двоичное, найдите число в правом столбце и возьмите соответствующую запись слева.
5 сентября 2025

В прошлых постах мы обсуждали задачу обмена значениями двух переменных. Здесь представляем симулятор для трёх переменных. Три круга обозначают переменные, их цвета — значения. Шесть кнопок покрывают присваивания a=b, b=a, b=t, t=b, a=t и t=a. Нажмите кнопку, и присваивание произойдёт сразу.
Мы использовали React для создания приложения и Vite для сборки. Было несколько интересных моментов, о которых расскажем позже. Начнём с задачи: как расположить три круга в вершинах равностороннего треугольника?
Есть несколько подходов:
29 августа 2025

Чтобы решать задачи реального мира, нужно выполнять операции с числами. В JS используются "*" для умножения, "/" для деления и "+", "-" для сложения и вычитания. Откройте консоль браузера и введите выражения 2*2, 5-3, 8/4, 6*6. В C++ и Python есть хитрые правила для дробного деления. В JS результат — число с плавающей точкой. Чтобы округлить его, примените функции Math.ceil или Math.floor.
Чтобы писать сложные программы, принимающие нетривиальные решения, объединяйте простые логические высказывания в более сложные конструкции. Например, если мы хотим определить, что x слишком мал или слишком велик, нужно объединить выражение (x < 4) с (x > 7). Каждое из них имеет булев тип. Чтобы объединить простые булевы выражения в сложное, используем логические операторы: "||" — или, "&&" — и, "!" — не. Таким образом, выражение записывается как (x < 4) || (x > 7).
Если нужно упаковать данные в переменную и работать на уровне битов, пригодятся побитовые операторы "|", "&", "^", "~". Это достаточно продвинутая техника, которую не используют каждый день, но иногда она может выручить.
22 августа 2025

До сих пор мы только присваивали значения переменным, и казалось, что ничего интересного сделать нельзя. Но есть известная задача: как обменять значения двух переменных? Это важная часть сортировочных алгоритмов. Попробуйте подумать. У вас есть две переменные:
let a = 5, b = 8;
...
console.log("a=", a, "b=", b);Ваша задача — вставить код вместо ..., чтобы вывод был: a=8, b=5. Разумеется, решение должно быть универсальным и использовать присваивания между переменными. Учтите, что выражения a = b или b = a сразу портят игру: одно из значений теряется. Избежать этой ловушки можно, введя третью переменную. Попробуйте написать свою программу и протестировать её в консоли браузера.
Получившийся код — известная функция «swap», которую можно встретить в библиотеках. Более сложная и менее известная задача — обменять значения без введения третьей переменной. Здесь можно подумать о других операциях, кроме чистого присваивания.
Если застряли, загляните на наш GitHub: three, minus и xor. Также можно поиграть в наш симулятор обмена «ref».
17 августа 2025

В языках вроде C++, Java и Go нельзя использовать переменную до её объявления. JavaScript дважды просматривает файл, сначала обрабатывая объявления.
Затем выполняется программа, и объявления как бы поднимаются наверх. var-программа может вывести undefined, а «временная мёртвая зона» заставляет let и const выбросить ошибку.
15 августа 2025

Ключевые слова var, let и const позволяют создать новую переменную и задать ей начальное значение. var — старая конструкция, сейчас она устарела. Чтобы создать переменную с неизменяемым значением, используйте const. Для переменной, значение которой будет меняться, используйте let.
Важно понимать, является ли ваше значение примитивом или объектом. const a = 5 полностью запрещает любые изменения, потому что 5 — примитивный тип, и утверждение «значение 5 хранится в переменной a» остаётся верным. А const b = [5] запрещает писать b = [6], но позволяет менять элементы массива, например b[0] = 777. Это происходит потому, что значение b — ссылка на массив; мы читаем эту ссылку из переменной и затем обращаемся к массиву по индексу.
8 июля 2025

Память компьютера состоит из нулей и единиц. Чтобы выполнять вычисления, рисовать картинки и отправлять сообщения, мы должны придать им смысл. Бит — это 0 или 1. Восемь бит — байт. Группы байтов могут хранить символы, числа, значения «истина/ложь». Тип говорит, какой смысл мы вкладываем в набор битов.
В JavaScript есть примитивные типы: Number, String, Boolean, Undefined, Null. Когда мы работаем с ними, можно сказать «значение находится в переменной», и результаты операций предсказуемы. «a=b» читаем как «берём значение из b и кладём его копию в a».
Есть и ссылочные типы: Object, Array, Function. В этом случае переменная содержит ссылку на объект где-то в памяти компьютера. «a=b» означает «теперь a ссылается на тот же объект, что и b», поэтому изменения через b затрагивают значение a.
let a = 5; let b = a; b = 8; console.log(a,b) // 5, 8 let a = [5]; let b = a; b[0] = 8; console.log(a, b) // [8], [8]