Первый код на JavaScript: Ритуал посвящения в магию
Откройте любую книгу по программированию на любом языке. Первая глава, первый пример, первая программа - всегда одна и та же. Она выводит на экран два слова: «Привет, мир».
Это не просто традиция. Это магический ритуал посвящения. Это момент, когда вы перестаёте быть просто пользователем компьютера и становитесь тем, кто говорит с машиной на её языке. Это ваш первый разговор с бесконечностью.
В этой статье мы не просто напечатаем console.log("Привет, мир"). Мы разберём каждую букву, каждую скобку и, главное, поймём, что на самом деле произошло в тот миг, когда вы запустили свой первый JavaScript.
Приготовьтесь. Сейчас будет волшебство.
Часть 1. Три способа сказать «Привет»
Представьте, что вы учитесь здороваться на новом языке. Можно шепнуть себе под нос. Можно крикнуть в рупор. А можно написать записку и передать другу. JavaScript даёт вам ровно три способа поприветствовать мир. И каждый важен.
Способ первый: Шёпот в консоль (для ваших ушей)
Это самый честный способ. Никто, кроме вас, не увидит результат. Зато вы увидите его мгновенно.
Что делать:
- Нажмите F12 (или Ctrl+Shift+I в Windows, Cmd+Option+I на Mac).
- Перейдите на вкладку Console.
- Напечатайте вот это:
javascript
console.log("Привет, мир");
- Нажмите Enter.
Что вы увидите: В консоли появится строка Привет, мир. Всё.
Что произошло: Вы поздоровались с машиной, и она вежливо ответила. Это ваш личный диалог. Никто из посетителей вашего сайта этого не увидит. Зато вы можете использовать этот способ, чтобы отлаживать код, проверять переменные и чувствовать пульс программы.
Запомните: console.log() - это ваш лучший друг на ближайшие годы. Он будет с вами в 3 часа ночи, когда вы будете искать неуловимую ошибку. Он не предаст.
Способ второй: Крик с холма (для всех)
Хотите, чтобы ваше приветствие увидел каждый, кто откроет страницу? Тогда вам нужен не шепот в консоль, а текст прямо на экране.
Что делать:
Создайте файл index.html и напишите в нём:
Откройте этот файл в браузере. Увидели? Слова «Привет, мир!» появятся прямо на странице, сразу после заголовка.
Предупреждение: document.write() - это как крик в библиотеке. Он работает, но считается устаревшим и грубым методом. В современном мире его используют редко, но для первого раза - самое то.
Способ третий: Элегантное прикосновение (как делают профи)
Самый правильный, самый красивый, самый современный способ. Вы не кричите и не шепчете. Вы находите место на странице и меняете его содержимое.
Что делать:
Создайте HTML-файл с пустым местом для приветствия:
Откройте в браузере. Увидите жирное «Привет, мир!» в том месте, где был пустой контейнер.
Почему это круто: Вы не переписываете всю страницу, не выводите текст в случайное место. Вы точно знаете, куда пойдёт ваше сообщение. Это управляемая магия. Именно так работают все современные сайты.
Часть 2. Анатомия одной строчки: Что мы только что написали?
Давайте разберём наш первый пример до костей. Возьмём самую простую версию:
javascript
console.log("Привет, мир");
Смотрите на эту строчку как инопланетянин, который впервые видит человеческий язык. Что здесь происходит?
console - это блокнот браузера
console — это специальный объект, который браузер даёт нам «из коробки». Он представляет собой панель разработчика. Думайте о console как о секретном кармане браузера, куда можно записывать заметки.
.log - действие (метод)
Точка между console и log означает: «возьми у консоли её внутренний инструмент под названием log». log — это действие, команда, которая говорит: «запиши что-нибудь в журнал».
Можно провести аналогию: console — это ваш дневник. .log — это ручка, которой вы пишете.
() - приглашение к действию
Круглые скобки — это как рот, который открывается, чтобы что-то сказать. Внутри скобок вы кладёте то, что хотите передать.
"Привет, мир" - само сообщение
Это строка текста. Кавычки (двойные или одинарные — не принципиально) говорят JavaScript: «Внимание! То, что внутри — это текст, а не команда. Не пытайся это выполнить, просто возьми и покажи как есть».
; - точка в предложении
Точка с запятой — это знак препинания. Он говорит JavaScript: «Здесь команда заканчивается. Можно переходить к следующей». Без него JavaScript иногда путается. Лучше ставить всегда.
Часть 3. Ошибки - это не страшно. Ошибки - это подсказки
Когда вы писали свой первый «Привет, мир», вы наверняка сделали одну из этих ошибок. И это нормально. Это часть пути.
Ошибка 1: Забыли кавычки
javascript
console.log(Привет, мир); // ❌ Ошибка!
Что увидите: Uncaught ReferenceError: Привет is not defined
Что это значит: JavaScript подумал, что Привет - это имя переменной (какой-то контейнер с данными). Он полез искать этот контейнер, не нашёл и расстроился.
Как исправить: Взять текст в кавычки.
Ошибка 2: Забыли точку
javascript
console log("Привет, мир"); // ❌ Ошибка!
Что увидите: Uncaught SyntaxError: Unexpected identifier
Что это значит: JavaScript ждал точку между console и log, а вместо неё увидел пробел. Он растерялся.
Как исправить: Поставить точку.
Ошибка 3: Разные кавычки
javascript
console.log("Привет, мир'); // ❌ Ошибка! Открыли двойные, закрыли одинарной
Что увидите: Uncaught SyntaxError: Invalid or unexpected token
Как исправить: Кавычки должны быть парными. Начали с двойной - закончите двойной. Начали с одинарной - закончите одинарной.
Важнейший навык, который вы должны освоить сейчас: Читать красные сообщения об ошибках. Не пугайтесь их. Они написаны английскими словами, но их смысл прост. Ошибка всегда говорит: «Я ждал вот это, а получил вот то. Смотри, вот здесь, на этой строчке».
Часть 4. Ваша первая интерактивность: Диалог с пользователем
«Привет, мир» - это хорошо. Но мир хочет отвечать. Давайте сделаем так, чтобы страница спросила у пользователя имя и поздоровалась лично с ним.
Вот полный код. Скопируйте его в HTML-файл и откройте в браузере:
Что здесь происходит (по шагам):
- document.getElementById - находим элементы на странице по их id.
- addEventListener - говорим браузеру: «Слушай, когда по кнопке кликнут - проснись и сделай что-то».
- prompt() - показывает диалоговое окно с полем для ввода.
- if (name) - проверяем, ввёл ли пользователь что-то (пустая строка или null считаются ложью).
- + для строк - склеиваем текст и переменную.
Вы только что написали программу, которая реагирует на человека. Это уже не просто «Привет, мир». Это диалог. Это начало настоящего программирования.
Часть 5. Психология первого кода: Почему это сложно и почему это нормально
Давайте честно. Когда вы напечатали console.log("Привет, мир") и нажали Enter, внутри, возможно, не случилось фейерверка. Вы подумали: «И всё? Это называется программирование?»
Я понимаю. Сложность не в том, чтобы написать эту строчку. Сложность в том, чтобы поверить, что из этих маленьких кирпичиков - переменных, функций, условий, циклов - строятся гигантские здания: Google Maps, YouTube, ChatGPT.
Каждый профессионал когда-то написал свой первый console.log. И в тот момент он ничего не понимал. Не понимал, зачем нужны точки с запятыми, почему кавычки бывают разными, куда делся результат.
Главный секрет: Вы не обязаны понимать всё сразу. Вы обязаны только делать следующий шаг. Изменить текст. Добавить переменную. Спросить имя. Попробовать что-то сломать, а потом починить.
Мантра начинающего разработчика:
- Я не знаю, как это работает.
- Но я знаю, что сейчас попробую.
- Если сломается - я прочитаю ошибку.
- Если не пойму - я загуглю.
- И так каждый день, пока однажды не обнаружу, что понимаю.
Часть 6. Что дальше? Ваш первый чек-лист роста
Вы написали «Привет, мир». Поздравляю. Но мир не ждёт. Вот что делать прямо сейчас, чтобы закрепить успех:
- Измените текст. Вместо «Привет, мир» напишите своё имя. Потом напишите целое предложение. Потом добавьте смайлик.
- Создайте переменную. Напишите let message = "Привет, мир"; а потом console.log(message);. Поймите: переменная хранит значение, а console.log его показывает.
- Сложите две строки. console.log("Меня зовут " + "Анна"); Поэкспериментируйте с пробелами.
- Спросите у пользователя. Используйте prompt(), сохраните ответ в переменную и выведите через console.log.
- Сломайте код намеренно. Уберите кавычку, уберите точку с запятой, поставьте заглавную букву в Console.log. Посмотрите на ошибку. Прочитайте её. Почините.
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
Структура кода JavaScript: Тайная архитектура цифрового собора
Представьте, что вы строите дом. Можно навалить кучу кирпичей, досок и гвоздей в одну огромную гору. Домом это не станет. А можно разложить фундамент, возвести стены, проложить коммуникации, поставить крышу. Разница между горой материалов и домом - структура.
Точно так же и с кодом. Можно написать программу одной сплошной строчкой на 5000 символов. Она даже будет работать. Но разбираться в ней, исправлять ошибки и добавлять новые возможности будет невозможно. Ад для разработчика.
Хорошая структура кода - это не про красоту. Это про выживание проекта и сохранение рассудка программиста. В этой статье мы разберем правила, традиции и магию организации кода на JavaScript. От мельчайших кирпичиков до архитектуры всего собора.
Часть 1. Инструкции: Атомы вашей программы
Программа на JavaScript состоит из инструкций (statements). Инструкция - это приказ. Законченное действие.
Вот примеры инструкций:
Каждая инструкция - как одно предложение в книге. Предложения отделяются друг от друга.
Точка с запятой: Спор на миллион
В JavaScript инструкции можно разделять точкой с запятой ;. А можно - переводом строки. Язык достаточно умён, чтобы понять, где заканчивается одна инструкция и начинается другая.
И тут начинается религиозная война.
Одни разработчики ставят точки с запятой всегда. Другие - почти никогда. Третьи ставят иногда, создавая хаос.
Правда в том, что JavaScript иногда ошибается. Есть редкие ситуации, когда перевод строки не спасает. Например:
JavaScript вставит точку с запятой после return, и функция вернёт undefined. Тело объекта никогда не выполнится.
Мой вам совет: Ставьте точку с запятой в конце каждой инструкции. Это как пристёгиваться ремнём безопасности - лишняя привычка, которая однажды спасёт вам жизнь.
Часть 2. Пробелы и отступы: Невидимая архитектура
JavaScript игнорирует лишние пробелы, табуляции и переводы строк. Компьютеру всё равно, как вы расположите код. Но человеку - не всё равно.
Сравните два варианта одного и того же кода:
Вариант 1 (ужас):
Вариант 2 (красота):
Код делает одно и то же. Но во втором варианте вы за секунду понимаете логику. В первом - напрягаете глаза и мозг.
Золотые правила форматирования
- Пробелы вокруг операторов: let sum = a + b (а не let sum=a+b).
- Пробел после запятой: [1, 2, 3] (а не [1,2,3]).
- Пробел после if, for, while: if (condition) (а не if(condition)).
- Отступы внутри блоков: 2 или 4 пробела (или табуляция). Выберите один стиль и придерживайтесь его везде.
Главный секрет: Хороший код читается как проза. Он дышит. У него есть ритм.
Часть 3. Блоки кода: Комнаты в доме
Блок кода — это группа инструкций, объединённых фигурными скобками { ... }. Блок создаёт новую «комнату» в вашей программе.
Блоки используются везде:
- В функциях: function sayHello() { ... }
- В условиях: if (age > 18) { ... }
- В циклах: for (let i = 0; i < 10; i++) { ... }
Важнейшее правило: Внутри блока можно создавать переменные, которые не видны снаружи (через let и const). Это называется область видимости. Мы ещё вернёмся к этому в отдельной статье.
Стиль расстановки скобок: Ещё одна война
Открывающую скобку можно поставить на той же строке, что и объявление:
А можно — на новой строке:
В мире JavaScript победил первый вариант (египетские скобки). Его используют в подавляющем большинстве проектов, включая React, Vue, Node.js. Запомните этот стиль - он станет вашим родным.
Часть 4. Комментарии: Разговор с будущим собой
Комментарии - это текст, который JavaScript полностью игнорирует. Он для людей. Для тех, кто будет читать ваш код через день, месяц или год. И для вас самого через полгода (вы удивитесь, как много забываете).
Однострочные комментарии
Две косые черты // - всё, что после них на этой строке - игнорируется
Многострочные комментарии
/* и */ - всё, что между ними, игнорируется. Удобно для больших пояснений.
Когда писать комментарии (а когда - не надо)
Плохой комментарий (бесполезный):
Хороший комментарий (объясняет ПОЧЕМУ, а не ЧТО):
Лучше комментария - понятный код:
Золотое правило: Комментируйте «почему», а не «что». Что делает код - понятно из самого кода. Почему он делает это именно так - часто требует пояснений.
Часть 5. Строгий режим: Дисциплина внутри
В начале вашего пути вы могли заметить странную строчку в некоторых примерах:
'use strict';
Или:
"use strict";
Это строгий режим. Он включает более жёсткие правила для JavaScript.
Что меняется?
Без 'use strict' (нестрогий режим):
С 'use strict':
Строгий режим превращает многие «молчаливые ошибки» в явные исключения. Он делает JavaScript более безопасным и предсказуемым.
Где включать?
- В современных проектах (модули, фреймворки) - он включён по умолчанию.
- В старом коде или в консоли браузера - включайте сами в начале файла или функции.
Совет: Всегда используйте 'use strict' в своих скриптах, если не работаете с современными модулями (там он автоматический). Это как пристегнуться в машине - привычка, которая однажды спасёт вас от глупой ошибки.
Часть 6. Организация файлов: Архитектура большого дома
Когда проект вырастает больше 100 строк, держать весь код в одном файле становится невозможно. Пора разбивать.
Правило одного назначения
Один файл - одна ответственность.
Подключение файлов в HTML
Важен порядок: файлы подключаются в том порядке, в котором они нужны. Если user.js использует функцию из utils.js, то utils.js должен быть подключен выше.
Часть 7. Антипаттерны: Как НЕ надо структурировать код
1. Глобальный сброс (плохо)
2. Спагетти-код (очень плохо)
3. Магические числа (плохо)
Исправление:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Переменные в JavaScript: Именованные сокровища в мире кода
Представьте, что ваша память - это огромный склад. Вы приходите туда, кладёте что-то на хранение, а потом возвращаетесь, чтобы забрать. Но если вы просто бросите вещи посреди склада, вы никогда их не найдёте. Вам нужны коробки с наклейками.
Переменные в программировании - это именно такие коробки. Вы кладёте туда данные (числа, текст, сложные объекты), наклеиваете имя и в любой момент можете заглянуть внутрь или положить что-то новое.
В этой статье мы разберём всё о переменных в JavaScript. Не просто «как написать let x = 5», а глубокое понимание: какие бывают переменные, чем они отличаются, как их правильно называть и почему это важно для вашей карьеры разработчика.
Часть 1. Что такое переменная? Метафора с коробкой
Давайте закрепим метафору. Переменная - это коробка с тремя важными свойствами:
- У неё есть имя - этикетка на коробке.
- У неё есть содержимое - то, что лежит внутри.
- Её можно переиспользовать - вытащить одно, положить другое.
В коде это выглядит так:
Ключевая идея: Переменная - это не само значение. Это ссылка на значение. Как ярлык на коробке, а не сама коробка.
Часть 2. Три способа создать переменную: var, let и const
В JavaScript есть три ключевых слова для создания переменных. Это как три типа коробок: картонные (для всякого), пластиковые контейнеры (удобные) и сейфы (нельзя открыть заново).
let - современный стандарт (пластиковый контейнер)
Появился в 2015 году (ES6). Сейчас используется в 99% случаев.
Особенности let:
- Значение можно менять сколько угодно раз.
- Живет внутри блока { ... }, где создана.
- Нельзя использовать до объявления (временно мёртвая зона).
const - константа (сейф)
Тоже появился в ES6. Создаёт переменную, которую нельзя переназначить.
Важнейшее уточнение: const защищает только саму переменную от переназначения. Если внутри сложный объект, его свойства менять можно.
Когда использовать const: Всегда, если вы не планируете менять значение. Это делает код понятнее. Другие разработчики (и вы сами через месяц) увидят const и сразу поймут: «эта переменная никогда не изменится».
var - старый режим (картонная коробка)
Существовал всегда (с 1995 года). Сейчас его использование считается плохим тоном в современном коде.
Почему var плох:
- Игнорирует блоки. Переменная var живёт внутри всей функции, даже если создана внутри if или цикла. Это приводит к неожиданным ошибкам.
- Можно использовать до объявления. JavaScript поднимает var вверх (hoisting), но значение будет undefined. Путаница гарантирована.
- Можно переобъявлять. Один и тот же var в одной функции - и компилятор не ругается.
Вердикт: Забудьте про var. Используйте let и const. Даже если вы встретите var в старом коде, теперь вы знаете, почему это плохо.
Часть 3. Правила именования: Как назвать коробку, чтобы не стыдно
Назвать переменную - это искусство. Хорошее имя делает код понятным без комментариев. Плохое имя превращает простую программу в головоломку.
Запрещённые символы (нарушать нельзя)
- Нельзя начинать с цифры: 1user - ошибка.
- Нельзя использовать дефис: user-name - минус воспринимается как вычитание.
- Нельзя использовать пробелы.
- Нельзя использовать специальные символы, кроме _ и $.
Зарезервированные слова (нельзя использовать)
JavaScript уже использует некоторые слова для своих нужд: let, const, if, for, function, return, class, new, this, try, catch и десятки других. Не называйте переменные так.
Рекомендации (можно нарушать, но не стоит)
1. Используйте понятные английские имена (или транслит).
2. Используйте camelCase (верблюжий стиль).
В JavaScript принято писать имена переменных с маленькой буквы, а каждое следующее слово начинать с заглавной.
3. Имена должны быть достаточно длинными, чтобы быть понятными, и достаточно короткими, чтобы не мешать читать.
4. Булевы переменные (true/false) часто начинаются с is, has, can.
Часть 4. Объявление и инициализация: Два этапа жизни переменной
Когда вы работаете с переменной, происходит два разных действия:
Объявление (declaration)
Вы говорите JavaScript: «Я хочу переменную с таким именем».
После объявления переменная существует, но её значение — undefined (особое значение, означающее «значение не задано»).
Инициализация (initialization)
Вы впервые кладёте значение в переменную.
Можно объединить оба шага:
Важное различие с const
const требует инициализации при объявлении. Нельзя сначала объявить, а потом присвоить.
Часть 5. Динамическая типизация: Переменные-хамелеоны
JavaScript - язык с динамической типизацией. Это умное словосочетание означает, что одна и та же переменная может хранить значения разных типов в разное время.
Это удобно? Да, для маленьких скриптов. Это опасно? Да, для больших проектов. Когда вы видите переменную data, и она сначала была числом, потом массивом, потом строкой - вы сойдёте с ума, пытаясь понять, что сейчас внутри.
Совет: Старайтесь, чтобы переменная хранила один тип данных на протяжении всей жизни. Если вам нужно хранить число - пусть всегда будет число. Если вы меняете тип - подумайте, может, стоит создать новую переменную?
Часть 6. Область видимости: Где живёт переменная?
Область видимости (scope) - это территория, внутри которой переменная доступна. За пределами этой территории переменная невидима.
Глобальная область (внешний мир)
Переменная, объявленная вне всех функций и блоков, называется глобальной. Она доступна везде.
Предупреждение: Глобальные переменные - это зло (почти всегда). Они создают хаос, потому что любая часть программы может их изменить. Вы никогда не будете уверены, кто и когда поменял глобальную переменную.
Блочная область (let и const)
let и const живут внутри блока { ... }, где созданы.
Функциональная область (var)
var живёт внутри всей функции, игнорируя блоки.
Именно поэтому var опасен. Он «выпрыгивает» из блоков и создаёт неожиданные эффекты.
Часть 7. Временная мёртвая зона: Тёмная сторона let и const
У let и const есть особенность: нельзя использовать переменную до её объявления.
Промежуток от входа в блок до строки с let называется временной мёртвой зоной (Temporal Dead Zone, TDZ). В этой зоне переменная существует, но доступа к ней нет.
У var такой зоны нет:
Почему TDZ — это хорошо? Потому что он ловит ошибки, когда вы случайно используете переменную до того, как положили в неё значение.
Часть 8. Практическое руководство: Как выбирать между let и const
Вот простая блок-схема для принятия решения:
- Мне нужно менять значение позже? → let
- Значение никогда не изменится? → const
Золотой стандарт: По умолчанию используйте const. Если компилятор (или вы сами) понимаете, что значение нужно менять - переключитесь на let. Такой подход защищает от случайных изменений.
Часть 9. Типичные ошибки новичков (и как их не совершать)
Ошибка 1: Использовать переменную без объявления
Ошибка 2: Переобъявлять переменную в той же области
Ошибка 3: Путать let и const
Ошибка 4: Использовать const со сложными объектами и ожидать полной неизменности
Заключение: Переменные - это алфавит программирования
Вы не можете написать ни одной программы без переменных. Это самый фундаментальный строительный блок. Но просто знать let x = 5 - это как выучить букву «А» и думать, что вы владеете русским языком.
Настоящее мастерство приходит, когда вы:
- Интуитивно выбираете между let и const.
- Даёте переменным осмысленные имена, которые говорят сами за себя.
- Понимаете, где живёт переменная и кто имеет к ней доступ.
- Избегаете глобальных переменных, как огня.
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
Охота на призраков: Полное руководство по типам данных в JavaScript (и почему typeof null - это баг, а не зверь)
JavaScript часто называют «странным» языком. Новички ненавидят его за NaN !== NaN, а профи используют эти странности, чтобы писать код короче, чем смс-сообщение.
Главная магия (и боль) JS кроется в его системе типов. Официально в языке 8 типов. Не 5, не 7, а 8. И один из них - «призрак».
Давайте разберем каждого зверя лично.
Часть 1. Примитивы: Атомы данных
В JavaScript примитивы - это самые простые кирпичики. Они не имеют методов (кроме тех, что им одалживает обертка), неизменяемы и хранятся по значению.
1. undefined - «Я обещал, но забыл»
Это тип для переменных, которые существуют, но в которых ничего нет.
Интересный факт: undefined можно присвоить переменной (хотя это плохая идея). Это не ошибка, это состояние «пустоты».
2. boolean - Простой выбор
Либо true, либо false. Казалось бы, что тут сложного? Сложность в том, что все в JS может стать boolean через двойное отрицание (!!).
3. number - Математический сюрреализм
В отличие от других языков, в JS нет отдельного типа для целых чисел (int) и дробей (float). Есть только 64-битное число с плавающей точкой (IEEE 754).
Из-за этого:
Но есть и спецзначения:
- Infinity (результат деления на 0)
- -Infinity
- NaN (Not a Number). Ловушка: NaN не равен сам себе. Проверять надо через Number.isNaN().
4. bigint — Спаситель гигантов
Появился недавно. Нужен, когда чисел с плавающей точкой перестает хватать для точных вычислений (например, ID в базах данных).
5. string - Строка-паровозик
В JS строки иммутабельны. Вы не можете изменить символ внутри существующей строки, только создать новую.
javascript
let str = "Hello";
str[0] = "Y";
console.log(str); // "Hello" (не изменилась!)
Есть забавный момент: строки любят притворяться объектами.
Но это потому, что JS на доли секунды создает объект-обертку String, выполняет метод и уничтожает его.
6. symbol - Уникальный ключ
Этот тип создан для того, чтобы создавать уникальные идентификаторы. Даже если вы создадите два символа с одинаковым описанием, они не равны.
Их суперсила: свойства, ключами которых служат символы, не видны в циклах for...in и игнорируются JSON.stringify().
Часть 2. «Отец и Мать»: Объект
7. object - Единственный сложный тип
Всё, что не является примитивом (из пп. 1–6), - это объект. Массивы? Объекты. Функции? Тоже объекты (особого вида). Дата? Объект.
Главное отличие от примитивов: объекты хранятся по ссылке.
8. null - Тайный агент
Вот тут начинается детективная история. Согласно спецификации, null - это отдельный тип (Null). Но...
Это официально признанная ошибка языка, которую не могут исправить 20 лет, потому что сломается миллион сайтов. null означает «значения нет, и оно задано намеренно», в отличие от undefined («значения нет, и я в шоке»).
Часть 3. Таблица превращений (Самое важное)
В JS работает неявное приведение типов. Если вы используете +, == или if(), JS сам решит, кем стать.
Запомните «Ложные» значения (Falsy). Их всего 8, остальные - истинные (Truthy):
- false
- 0
- "" (пустая строка)
- null
- undefined
- NaN
- 0n (BigInt ноль)
- document.all (исторический артефакт браузеров)
Секретное оружие:
Если вы хотите строгое сравнение (без сюрпризов) — используйте ===.
Итог: Как думать о типах в JS
Не пытайтесь заставить JS быть Java или C#. Примите его философию:
- Примитивы - это данные (числа, строки). Они равны по значению.
- Объекты - это структуры. Они равны, только если это один и тот же объект в памяти.
- typeof - ваш друг, но он врет про null.
- NaN - это психически больное число, которое не помнит себя.
Когда вы поймете, что [] + [] возвращает пустую строку, а [] + {} возвращает "[object Object]", вы перестанете бояться и начнете использовать динамическую природу JS себе на пользу.
Помните: в JavaScript нет «правильных» или «неправильных» типов. Есть только ваше понимание того, как движок преобразует один тип в другой за кулисами.
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
Троица древних магов: Почему alert, prompt и confirm до сих пор живы (и когда их лучше не трогать)
В мире современного JavaScript, где царят React, Vue и Svelte, есть три метода, которые выглядят как дедушки на пенсии. Они блокируют всё, выглядят уродливо и не кастомизируются. Но... каждый фронтенд-разработчик обязан знать их в лицо.
Знакомьтесь: alert, prompt и confirm. Троица, которая замораживает ваш интерфейс ледяным дыханием.
Часть 1. alert() - "Просто скажи им"
Самый простой и самый жестокий.
Что происходит в этот момент?
Движок браузера останавливает ВСЁ. Скрипты не выполняются. Анимация не рисуется. Пользователь не может кликнуть на кнопку или прокрутить страницу. Мир замер в ожидании одного единственного действия — нажатия "OK".
Это называется синхронная блокировка.
Когда использовать?
- В учебных целях (чтобы новички видели результат сразу).
- В отладке (быстрее, чем ставить debugger).
- Для критических ошибок перед тем, как скрипт рухнет окончательно.
Когда не использовать?
Никогда в продакшене. Пользователь ненавидит, когда у него крадут управление.
Хитрость: alert всегда возвращает undefined. Ему нечем ответить.
Часть 2. confirm() - "Родители или пицца?"
Этот маг умеет задавать вопросы с двумя вариантами ответа.
Он возвращает boolean:
- true - нажали "OK"
- false - нажали "Отмена" или крестик (да, крестик в углу тоже считается "false")
Классический паттерн использования:
Подводный камень:
На мобильных браузерах поведение может отличаться. Некоторые оборачивают confirm в асинхронные вызовы, но старый добрый десктопный Chrome остановит всё железобетонно.
Часть 3. prompt() - "Введи своё имя, странник"
Самый опасный и мощный из троицы. Он не только спрашивает, но и просит ввода текста.
Возвращаемые значения (тут ловушка!):
- Если ввели текст и нажали OK → строка (string).
- Если нажали Отмена → null.
- Если нажали OK, но поле пустое → пустая строка "".
Главная ошибка новичка:
prompt всегда возвращает строку! Сравнение строки с числом приведет к неожиданным результатам. "100" > 18 - true, но "5" > 18 тоже true, потому что строки сравниваются посимвольно!
Правильно:
Часть 4. Почему все их ненавидят (и правильно делают)
Эти три метода нарушают главный принцип современного веба - неблокирующий ввод-вывод.
Представьте: у вас на странице таймер обратного отсчета. Вы вызываете prompt("Введите код"). Таймер... останавливается. Пока пользователь думает, секунды не идут. Это ужасный опыт.
Более того:
- Их нельзя стилизовать через CSS.
- Они работают только в браузере (не в Node.js).
- В некоторых вкладках, которые долго не использовались, браузер может их подавлять.
Часть 5. А что вместо них?
В реальных проектах используют кастомные модальные окна (библиотеки или свои на div + CSS):
- React-попапы (через состояние isOpen)
- SweetAlert2 - красивейшие диалоги, которые не блокируют поток
- window.prompt в современных PWA запрещён из соображений безопасности
Но! Для прототипов, скриптов в консоли браузера и быстрых тестов троица незаменима.
Итог: Алхимия взаимодействия
Запомните мантру:
alert - крик в пустоту. Ты сказал, но не спросил.
confirm - да/нет. Пульс пользователя.
prompt - опасная игрушка. Всегда возвращает строку или null. Всегда проверяй тип!
Золотое правило безопасности:
Никогда не доверяйте данным из prompt. Пользователь может ввести "<script>alert('XSS')</script>" или просто сломать вашу логику. Всегда валидируйте и санируйте ввод.
И помните: даже если вы работаете с современным фреймворком, эти три метода - часть ДНК JavaScript. Они были в Netscape Navigator и останутся в браузере навсегда. Как ископаемые, которые иногда полезно откопать для быстрого дебага.
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
Ад и рай JavaScript: Полное руководство по преобразованию типов (или почему [] + [] - пустая строка)
Если вы пишете на JS достаточно долго, у вас был момент, когда код работал, но вы не поняли почему. Или не работал, хотя всё правильно. Скорее всего, виновато неявное приведение типов.
В JavaScript действует философия: "Я, конечно, не знаю, что ты имел в виду, но я попробую угадать". Иногда это удобно. Иногда это порождает монстров вроде (!+[]+[]+![]).length.
Давайте разберем 3 главных правила превращений.
Правило №1: Строгое vs Нестрогое сравнение
В JS два оператора сравнения:
- == (лоскутное одеяло) - приводит типы к одному.
- === (священный грааль) - сравнивает без приведения.
Мантра разработчика: Всегда используй ===. == нужен только для проверки на null или undefined:
Правило №2: ToString, ToNumber, ToBoolean - Три кита
Когда JS нужно преобразовать что-то во что-то, он вызывает внутренние абстрактные операции.
1. ToBoolean (Что правда, а что ложь)
Запомните 8 лживых значений (falsy). Всё остальное - истина (truthy).
Шок-контент:
2. ToNumber (Математический хаос)
Когда JS ждет число, а получает что-то другое:
Самый странный пример:
3. ToString (Всё в строку)
Здесь всё проще, но есть нюансы:
Правило №3: Магия оператора +
Оператор плюс - самый непредсказуемый в JS. Он перегружен: работает и для чисел, и для строк.
Алгоритм работы +:
- Если хотя бы один операнд - объект, преобразовать его в примитив.
- Если после преобразования любой операнд - строка, сделать строковую конкатенацию.
- Иначе - численное сложение.
Разбор культовых примеров:
Правило №4: Неявное преобразование в логических контекстах
if, while, &&, ||, ! - все они приводят к boolean.
Классический парадокс:
Правило №5: Логические операторы && и || (Коварные)
Они возвращают не true/false, а один из операндов!
Итог: Как не сойти с ума
- Используйте === (почти всегда).
- Помните про falsy-значения (их всего 8).
- Плюс + - коварен (он любит строки).
- Все остальные операторы (-, *, /) любят числа.
- В if() и циклах - [] и {} это true (сюрприз!).
Проверьте себя: что выведет этот код?
JavaScript не пытается вас запутать. У него просто очень своё чувство логики. И когда вы поймёте эти правила, код перестанет быть магией и станет предсказуемой инженерией. Ну... почти предсказуемой.
--------------------------------------------------------------------
--------------------------------------------------------------------
Танцы с числами: Полное руководство по операторам JavaScript (или как случайно получить -0)
Операторы в JavaScript — как швейцарский нож. Вроде всё просто: плюс, минус, умножить. Но стоит копнуть глубже, и вы найдете там грабли, о которые спотыкаются даже опытные разработчики.
Давайте разберемся, как на самом деле работает математика в самом непредсказуемом языке программирования.
Часть 1. Арифметика: Только цифры? А вот и нет!
Классический набор вам знаком:
Но дьявол в деталях.
Проблема №1: Деление на ноль
В нормальных языках это ошибка. В JavaScript — бесконечность:
Infinity ведет себя как математическая бесконечность:
Проблема №2: Точность чисел с плавающей точкой
Классика жанра:
Почему так происходит? Компьютер хранит числа в двоичной системе, а 0.1 и 0.2 — бесконечные дроби в двоичном виде. Отсюда погрешность.
Решение для денег: храните копейки в целых числах или используйте библиотеки.
Часть 2. Операторы присваивания: Сахар для ленивых
Все знают =, но есть и его комбо-версии:
Лайфхак с конкатенацией строк:
Часть 3. Инкремент и декремент: ++ и -- (Внимание, ловушка!)
Эти операторы увеличивают или уменьшают число на 1. Но есть префиксная и постфиксная форма — и разница огромна!
Запомните мантру:
- x++ - "возьми x, потом увеличь"
- ++x - "увеличь, потом возьми"
Реальный баг:
Часть 4. Операторы сравнения: Секретный уровень
Почему == - зло:
Правило профессионала: Используйте === всегда. Исключение — проверка на null или undefined:
Часть 5. Логические операторы: Не всё то правда, что true
Секрет: Они возвращают не true/false!
Полезные паттерны:
Часть 6. Побитовые операторы: Для гуру (и флагов)
Они работают с 32-битным представлением чисел. Нужны редко, но знать стоит:
Реальный кейс - флаги:
Часть 7. Оператор typeof и instanceof: Кто ты?
typeof 42; // "number"
typeof "text"; // "string"
typeof undefined; // "undefined"
typeof null; // "object" (ОШИБКА ЯЗЫКА!)
typeof []; // "object" (массив — объект)
typeof {}; // "object"
typeof function(){}; // "function"
// instanceof проверяет принадлежность классу
[] instanceof Array; // true
{} instanceof Object; // true
Фикс для null:
javascript
function getType(value) {
if (value === null) return "null";
return typeof value;
}
Часть 8. Тернарный оператор: ? : (if в одну строку)
javascript
let age = 20;
let status = age >= 18 ? "Взрослый" : "Ребенок";
// Читается: "Если age >= 18, то 'Взрослый', иначе 'Ребенок'"
Можно вкладывать (но лучше не надо):
javascript
let message = score > 90 ? "Отлично"
: score > 70 ? "Хорошо"
: score > 50 ? "Нормально"
: "Плохо";
// Работает, но читается ужасно
Часть 9. Оператор запятая: Забытый реликт
Вычисляет все выражения и возвращает последнее:
javascript
let a = (5, 10, 15); // a = 15
let b = (x++, x * 2, x); // редко, но бывает в циклах
// Пример из реальной жизни (минификация кода)
for (let i = 0, j = 10; i < j; i++, j--) {
console.log(i, j);
}
Итог: Таблица приоритетов (шпаргалка)
Операторы имеют приоритет, как в школе: сначала скобки, потом умножение, потом сложение.
Самые важные в порядке убывания:
- () - группировка
- ++ -- ! typeof - унарные
- ** - степень
- * / % - умножение/деление
- + - - сложение/вычитание
- < > <= >= - сравнения
- === !== - строгие сравнения
- && - И
- || - ИЛИ
- ? : - тернарный
- = += *= - присваивания
Золотое правило: Если сомневаешься в приоритете =- поставь скобки. Код станет понятнее, а багов меньше.
javascript
// Вместо этого:
let result = a + b * c / d - e;
// Лучше так:
let result = a + ((b * c) / d) - e;
Помните: операторы — это инструменты. Они могут быть простыми и понятными, а могут — источником трудноуловимых багов. Используйте их с умом, и JavaScript скажет вам спасибо (ну, или хотя бы не кинет NaN в самый неподходящий момент).
----------------------------------------------------------------------------
----------------------------------------------------------------------------
Битва титанов: Правда и ложь в мире JavaScript (или почему 'a' > 'b' - это false)
Операторы сравнения — это судьи в мире кода. Они решают, кто больше, кто меньше, а кто равен. Но в JavaScript эти судьи иногда ведут себя как персонажи Льюиса Кэрролла — их логика странная, но если понять правила игры, всё встает на свои места.
Часть 1. Великолепная шестерка
Вот они, главные герои:
javascript
> // больше
< // меньше
>= // больше или равно
<= // меньше или равно
== // равно (с приведением типов) - ОПАСНЫЙ
=== // строго равно (без приведения) - БЕЗОПАСНЫЙ
!= // не равно (с приведением)
!== // строго не равно (без приведения)
На первый взгляд всё просто. Но давайте нырнем глубже.
Часть 2. Строгие против нестрогих: Дуэль на выживание
Строгие операторы (===, !==) - телохранители вашего кода
Они сравнивают два значения и никогда не приводят типы. Если типы разные — сразу false.
javascript
5 === 5 // true (число и число)
5 === "5" // false (число и строка - разные типы!)
true === 1 // false (логический и числовой)
null === undefined // false (разные типы!)
Нестрогие операторы (==, !=) - опасные дипломаты
Они пытаются подружить разные типы, приводя их к общему знаменателю.
javascript
5 == "5" // true (строка "5" стала числом 5)
true == 1 // true (true стал 1)
false == 0 // true (false стал 0)
null == undefined // true (специальное правило!)
Золотое правило: Всегда используйте === и !==. == нужен только в одном случае — проверка на null и undefined одновременно:
javascript
if (value == null) {
// Это сработает для null И для undefined
// Короче чем value === null || value === undefined
}
Часть 3. Сравнение чисел: Подводные камни
Проблема: NaN не равен сам себе
Это самый известный баг (или фича) в мире сравнений:
javascript
NaN === NaN // false! (шок)
NaN == NaN // false! (даже нестрогое не помогает)
Как проверить на NaN:
javascript
let result = 0 / 0; // NaN
// Старый способ (костыль)
isNaN(result); // true (но не идеален)
// Современный способ (ES6)
Number.isNaN(result); // true (безопасный)
Проблема: 0 и -0 - формально разные, но равны
Да, в JavaScript есть отрицательный ноль. И он ведет себя странно:
javascript
0 === -0; // true (равны!)
1 / 0; // Infinity
1 / -0; // -Infinity (разница есть!)
Object.is(0, -0); // false (метод, который видит разницу)
Часть 4. Сравнение строк: Лексикографический детектив
Строки сравниваются символ за символом по Unicode-кодам.
javascript
"a" > "b" // false (97 > 98? нет)
"ab" > "aa" // true (сравнили 'b' и 'a')
"2" > "10" // true! (сравниваем как строки: '2' > '1')
Важно: Это не число, это посимвольное сравнение!
javascript
"Apple" > "Banana" // false ('A' (65) < 'B' (66))
"apple" > "Banana" // true! ('a' (97) > 'B' (66))
Практический вывод: Для сортировки строк по алфавиту используйте localeCompare:
javascript
"apple".localeCompare("Banana"); // положительное число (с учетом регистра)
"apple".localeCompare("Banana", undefined, { sensitivity: 'base' }); // без учета регистра
Часть 5. Сравнение разных типов: Таблица превращений
Когда сравниваются разные типы, JS следует строгому алгоритму:
Правила для > < >= <=:
- Если оба операнда — строки → лексикографическое сравнение
- Иначе → преобразуем оба в числа и сравниваем
javascript
"5" > 3 // true (5 > 3)
"05" > 3 // true (5 > 3)
"5" > "10" // true (строковое сравнение: '5' > '1')
null > 0 // false (null → 0, 0 > 0? нет)
null >= 0 // true (null → 0, 0 >= 0? да)
undefined > 0 // false (undefined → NaN, NaN всегда false)
Ловушка с null и undefined:
javascript
null == 0 // false (специальный случай)
null >= 0 // true (null преобразовался в 0)
null > 0 // false
undefined == 0 // false
undefined > 0 // false
undefined < 0 // false (undefined → NaN, любое сравнение с NaN → false)
Часть 6. Сравнение объектов: Ссылка на сердце
Объекты сравниваются по ссылке, а не по содержимому:
javascript
{} == {} // false (разные объекты в памяти)
[] == [] // false (разные массивы)
let obj1 = { name: "JS" };
let obj2 = obj1;
obj1 == obj2; // true (одна и та же ссылка!)
Сравнение по содержимому: нужно писать свою логику или использовать библиотеки:
javascript
function shallowEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
let keys1 = Object.keys(obj1);
let keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
return keys1.every(key => obj1[key] === obj2[key]);
}
Часть 7. Культовые примеры (или "Почему никто не любит ==")
Давайте разберем самые безумные сравнения:
javascript
// 1. Массив и число
[] == 0 // true ([] → "" → 0)
[1] == 1 // true ([1] → "1" → 1)
[1,2] == 1 // false ([1,2] → "1,2" → NaN)
// 2. Логические и числа
true == 1 // true
false == 0 // true
true == "1" // true
true == "2" // false ("2" → 2, 1 == 2? нет)
// 3. Null и undefined (только пара)
null == undefined // true
null == null // true
undefined == undefined // true
// 4. Всё вместе
[] == ![] // true? Давайте разбираться!
// ![] → false (пустой массив truthy, отрицание → false)
// [] == false → [] == 0 → "" == 0 → 0 == 0 → true
// 5. Строка и объект
"0" == { valueOf() { return 0; } } // true (объект преобразовался в 0)
// 6. Абсурд
[] == [] // false (разные ссылки)
[] == ![] // true (смотри выше)
[] != [] // true (странно, да?)
Часть 8. Оператор Object.is(): Строгий, но честный
ES6 добавил метод, который сравнивает "почти как ===", но с двумя отличиями:
javascript
Object.is(NaN, NaN); // true (исправляет баг!)
Object.is(0, -0); // false (видит разницу)
Object.is(5, "5"); // false (как ===)
// Когда использовать: для специальных математических случаев
Object.is(1/0, Infinity); // true
Object.is(-0, 0); // false (если это важно для вашего алгоритма)
Часть 9. Практические паттерны (код, который вы будете писать каждый день)
Проверка на существование свойства:
javascript
if (obj.property !== undefined) { } // плохо (может быть свойство со значением undefined)
if ("property" in obj) { } // хорошо
if (obj.hasOwnProperty("property")) { } // еще лучше (своё свойство)
Безопасное сравнение с числом:
javascript
// Плохо
if (value > 10) { } // если value не число → NaN → false (но логика теряется)
// Хорошо
let num = Number(value);
if (!isNaN(num) && num > 10) { }
Проверка на null/undefined:
javascript
// Длинно
if (value === null || value === undefined) { }
// Коротко (безопасно)
if (value == null) { } // единственное легальное использование ==
Сравнение дат:
javascript
let date1 = new Date("2024-01-01");
let date2 = new Date("2024-01-01");
date1 == date2; // false (разные объекты)
date1 === date2; // false
date1.getTime() === date2.getTime(); // true (сравниваем числа)
+date1 === +date2; // тоже true (унарный плюс преобразует в число)
Часть 10. Таблица истины (шпаргалка)
Сравнение Результат Почему
null == undefined true Специальное правило
null === undefined false Разные типы
NaN == NaN false NaN не равен себе
[] == false true [] → "" → 0, false → 0
" " == false true "" → 0, false → 0
" \t\n" == 0 true Пробелы игнорируются
{} == {} false Разные объекты
[] == [] false Разные массивы
[1] == 1 true Массив → строка → число
"5" > 10 false "5" → 5, 5 > 10? нет
"5" > "10" true Строковое сравнение
Итог: Манифест сравнений
- Всегда используйте === и !== - это спасет вас от 99% багов.
- Исключение: value == null - единственное легальное использование ==.
- Помните про NaN - проверяйте через Number.isNaN().
- Строки сравниваются посимвольно - не путайте с числами.
- Объекты сравниваются по ссылке - для сравнения содержимого пишите свою логику.
- Object.is() - для специальных случаев (NaN, -0).
И главное: сравнения - это не магия. Это просто правила. Когда вы выучите эти правила, код перестанет вас удивлять. Ну... почти перестанет.
Финальный тест на понимание (попробуйте угадать):
javascript
console.log([] == []);
console.log([] == ![]);
console.log([1] == [1]);
console.log(" \t\r\n" == 0);
console.log(null >= 0);
Ответы: false, true, false, true, true. Если вы не ошиблись ни разу - вы настоящий джедай сравнений. Если ошиблись - ничего страшного, теперь вы знаете правильные ответы и механику за ними.
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
Дороги, которые мы выбираем: Полное руководство по if, else и тернарному оператору ?
Каждая программа - это дерево решений. Если пользователь авторизован - покажи ленту. Если пароль слишком короткий - попроси ввести новый. Если сегодня понедельник - предложи выпить кофе.
В JavaScript за все эти развилки отвечают условные конструкции. Они просты как кирпич, но из этих кирпичей можно построить как сарай, так и небоскреб. Давайте разберемся, как не провалиться в кроличью нору вложенных if.
Часть 1. if - Самый честный оператор
Конструкция if говорит: "Если условие правдиво - сделай это".
javascript
if (condition) {
// код выполнится, если condition приведётся к true
}
Ключевой момент: В скобках может быть что угодно. JavaScript сам приведет это к boolean по правилам, которые мы уже знаем (8 falsy-значений — всё остальное truthy).
javascript
if ("hello") { } // true (непустая строка)
if (0) { } // false (0 - falsy)
if ([]) { } // true (пустой массив - объект, объект - true)
if (null) { } // false
if (undefined) { } // false
Однострочный if (без фигурных скобок)
Можно писать без {}, если выполняется одна инструкция:
javascript
if (age >= 18) console.log("Добро пожаловать");
⚠️ Опасность: Без скобок выполнится только первая инструкция.
javascript
if (age >= 18)
console.log("Добро пожаловать");
console.log("Здесь скидка на пиво"); // Эта строка выполнится ВСЕГДА!
Правило профессионала: Всегда ставьте фигурные скобки. Даже для одной строки. Ваше будущее "я" скажет спасибо.
Часть 2. else - План Б
Когда условие ложно, вступает else:
javascript
if (temperature > 25) {
console.log("Надевай шорты");
} else {
console.log("Бери куртку");
}
else if - Лестница решений
Для множества вариантов:
javascript
if (score >= 90) {
grade = "A";
} else if (score >= 75) {
grade = "B";
} else if (score >= 60) {
grade = "C";
} else {
grade = "F";
}
Важно: Как только найдено первое совпадение, остальные не проверяются. Порядок имеет значение!
javascript
// ПЛОХО (неправильный порядок)
if (score >= 60) {
grade = "C"; // Сработает для 95, хотя должен быть A!
} else if (score >= 90) {
grade = "A"; // Сюда никогда не зайдем
}
Часть 3. Тернарный оператор ? : - if в миниатюре
Это единственный оператор в JS, который принимает три операнда:
javascript
let result = condition ? valueIfTrue : valueIfFalse;
Читается так: "Если условие истинно - верни то, что после ?, иначе - то, что после :".
javascript
let status = age >= 18 ? "взрослый" : "ребенок";
let message = isLoggedIn ? `Привет, ${name}!` : "Войдите в систему";
Когда использовать тернарный оператор:
✅ Хорошо: Простые присваивания
javascript
let className = isActive ? "btn-active" : "btn-inactive";
✅ Нормально: В JSX/шаблонах
jsx
<div>{isLoading ? "Загрузка..." : "Контент"}</div>
❌ Плохо: Вложенные тернарники (ад)
javascript
// Никогда так не пишите!
let result = a > b ? a > c ? a : c : b > c ? b : c;
// Лучше понятный if или Math.max
let result = Math.max(a, b, c);
❌ Ужасно: Тернарник без присваивания
javascript
age >= 18 ? console.log("ok") : console.log("no"); // Просто используйте if!
Золотое правило: Тернарник возвращает значение, if - выполняет действия.
Часть 4. Логические операторы как условные конструкции
&& и || можно использовать для ветвления (хотя это моветон):
javascript
// Старый трюк (раньше использовали для default значений)
let name = userName || "Гость"; // Если userName falsy → "Гость"
// Короткое замыкание (выполнить действие, если условие истинно)
isLoggedIn && fetchUserData(); // Вызовется только если isLoggedIn === true
// Современная альтернатива (ES2020) - оператор нулевого слияния
let name = userName ?? "Гость"; // Только если userName null/undefined
⚠️ Предупреждение: Не злоупотребляйте этим. if читается гораздо легче.
Часть 5. Антипаттерны (или "Как писать код, который ненавидят все")
Антипаттерн #1: Избыточное сравнение с true/false
javascript
// Плохо
if (isLoggedIn === true) { }
if (isFinished === false) { }
// Хорошо
if (isLoggedIn) { }
if (!isFinished) { }
Антипаттерн #2: Присваивание вместо сравнения
javascript
// Опечатка, которая сломает всё:
if (userName = "admin") { // Присваивание, а не сравнение!
// Всегда true (если "admin" - непустая строка)
}
// Правильно:
if (userName === "admin") { }
Защита: Некоторые пишут if ("admin" === userName) - "Yoda conditions". Выглядит странно, но защищает от опечаток.
Антипаттерн #3: Глубокая вложенность (Pyramid of Doom)
javascript
// Плохо (ад вложенности)
if (user) {
if (user.isLoggedIn) {
if (user.hasPermission) {
if (user.isActive) {
// do something
}
}
}
}
// Хорошо (ранний возврат)
if (!user) return;
if (!user.isLoggedIn) return;
if (!user.hasPermission) return;
if (!user.isActive) return;
// do something
Антипаттерн #4: Слишком умный тернарник
javascript
// Плохо (никто не поймет)
let result = a ? b ? c ? d : e : f : g;
// Хорошо (разбито на понятные куски)
let result;
if (a) {
if (b) {
result = c ? d : e;
} else {
result = f;
}
} else {
result = g;
}
Часть 6. Сравнение с switch (когда if становится тесно)
if-else хорош для условий с разными операторами (>, <, ===). Но когда вы проверяете одно значение на множество вариантов — присмотритесь к switch:
javascript
// Много if-else
if (day === "Monday") {
activity = "Работа";
} else if (day === "Tuesday") {
activity = "Работа";
} else if (day === "Wednesday") {
activity = "Работа";
} else if (day === "Saturday") {
activity = "Отдых";
} else if (day === "Sunday") {
activity = "Отдых";
} else {
activity = "Что-то странное";
}
// Тоже самое на switch (чище)
switch (day) {
case "Monday":
case "Tuesday":
case "Wednesday":
activity = "Работа";
break;
case "Saturday":
case "Sunday":
activity = "Отдых";
break;
default:
activity = "Что-то странное";
}
Когда switch не подходит: для сложных условий (>, <, &&, ||).
Часть 7. Реальные паттерны (код, который вы будете писать)
Паттерн #1: Guard clauses (ранние возвраты)
javascript
function processOrder(order) {
// Проверки в начале - стражи
if (!order) return { error: "Нет заказа" };
if (!order.items.length) return { error: "Пустой заказ" };
if (order.total <= 0) return { error: "Неверная сумма" };
// Основная логика (без вложенностей!)
return { success: true, total: order.total };
}
Паттерн #2: Объектный lookup вместо if-else
javascript
// Плохо (много if)
function getEmoji(weather) {
if (weather === "sunny") return "☀️";
if (weather === "rainy") return "🌧️";
if (weather === "cloudy") return "☁️";
if (weather === "snowy") return "❄️";
return "🌈";
}
// Хорошо (объект-словарь)
const emojis = {
sunny: "☀️",
rainy: "🌧️",
cloudy: "☁️",
snowy: "❄️"
};
const getEmoji = (weather) => emojis[weather] || "🌈";
Паттерн #3: Цепочка тернарников (читаемая)
Иногда тернарники можно объединять в цепочку, но только короткую и понятную:
javascript
// Приемлемо (короткая цепочка)
const size = height > 180 ? "XL"
: height > 170 ? "L"
: height > 160 ? "M"
: "S";
// Но для сложного лучше if-else
let size;
if (height > 180) size = "XL";
else if (height > 170) size = "L";
else if (height > 160) size = "M";
else size = "S";
Паттерн #4: Проверка наличия в массиве
javascript
// Плохо
if (role === "admin" || role === "moderator" || role === "editor") {
grantAccess();
}
// Хорошо
const allowedRoles = ["admin", "moderator", "editor"];
if (allowedRoles.includes(role)) {
grantAccess();
}
Часть 8. Подводные камни (или "Почему мой if не работает?")
Камень #1: Сравнение с NaN
javascript
let result = 0 / 0; // NaN
if (result === NaN) { } // Никогда не сработает (NaN !== NaN)
if (isNaN(result)) { } // Работает, но есть нюанс
if (Number.isNaN(result)) { } // Правильно
Камень #2: Объекты всегда true
javascript
let emptyBox = {};
if (emptyBox) { // true, даже если объект пустой!
console.log("Объект существует");
}
if (Object.keys(emptyBox).length === 0) { // Правильная проверка на пустоту
console.log("Объект пуст");
}
Камень #3: Строковые числа
javascript
let value = "10";
if (value > 5) { // true (строка "10" стала числом 10)
console.log("Сработало");
}
// Но будьте осторожны с ===
if (value === 10) { // false (строка !== число)
}
Итог: Манифест ветвления
- if - для всего. Простой, понятный, надежный.
- Тернарный оператор ? : - только для простых присваиваний в одну строку.
- Никогда не вкладывайте тернарники - это путь в безумие.
- Всегда используйте {} - даже для одной строки.
- Ранние возвраты (guard clauses) - спасают от пирамиды вложенности.
- Для множества однотипных проверок - используйте switch или объектный lookup.
И напоследок - цитата из мира реального кода:
"If you have more than 3 levels of nesting, your code is begging for a refactor. Listen to it."
Условное ветвление - это искусство выбора. И хороший разработчик знает не только синтаксис, но и когда какой инструмент применить. if для сложной логики, тернарник для простых присваиваний, switch для множества вариантов одного значения.
Выбирайте мудро. И ваш код будет читать не только компьютер, но и человек. А это, поверьте, гораздо важнее.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Логические иллюзии: Почему && возвращает число, а || - строку (и как это использовать)
В мире JavaScript логические операторы - это хамелеоны. На первый взгляд, они просто отвечают на вопросы "правда или ложь". Но загляните под капот - и вы увидите, что они возвращают не true и false, а оригинальные значения. И эта суперсила меняет всё.
Знакомьтесь: &&, || и ! - троица, которая управляет потоком вашего кода.
Часть 1. ! (Логическое НЕ) - Самый честный оператор
В отличие от своих собратьев, ! всегда возвращает boolean. Он берет значение, приводит его к boolean и инвертирует.
javascript
!true // false
!false // true
!"hello" // false (непустая строка → true → false)
!"" // true (пустая строка → false → true)
!0 // true
!42 // false
!null // true
!undefined// true
!NaN // true
Двойное НЕ (!!) - Дорогой boolean, пожалуйста
!! - это не отдельный оператор, а два подряд. Он приводит любое значение к его логическому эквиваленту:
javascript
!!"text" // true
!!0 // false
!![] // true (пустой массив - объект, объект - true)
!!null // false
Зачем это нужно? Когда вы точно хотите получить true или false, а не "правдоподобное" значение.
javascript
// Без !!
if (userCount) { } // Работает, но неявно
// С !! — явное приведение
let hasUsers = !!userCount; // точно true или false
Часть 2. || (ИЛИ) - Оператор-оптимист
|| ищет первое истинное значение. Он движется слева направо и останавливается на первой правде.
Секрет: || возвращает не true/false, а исходное значение, на котором остановился.
javascript
let result = value1 || value2 || value3;
// Алгоритм:
// 1. Проверить value1 → если truthy → вернуть value1
// 2. Если falsy → проверить value2 → если truthy → вернуть value2
// 3. Если все falsy → вернуть последнее значение
Примеры:
javascript
0 || 1 || 2 // 1 (первое truthy)
"" || "default" // "default"
null || undefined // undefined (оба falsy → последнее)
"hello" || "world" // "hello" (первое truthy)
Классические паттерны с ||
Паттерн #1: Значение по умолчанию (старый способ)
javascript
function greet(name) {
let userName = name || "Гость";
console.log(`Привет, ${userName}!`);
}
greet("Анна"); // Привет, Анна!
greet(""); // Привет, Гость! (пустая строка → falsy)
greet(undefined); // Привет, Гость!
⚠️ Внимание: Этот паттерн ломается на falsy-значениях, которые могут быть валидными:
javascript
let count = 0 || 10; // 10 (хотя 0 - валидное число!)
// Современное решение: оператор ?? (nullish coalescing)
let count = 0 ?? 10; // 0 (только null/undefined заменяет)
Паттерн #2: Выполнение первого существующего
javascript
let element = document.querySelector("#main")
|| document.querySelector(".content")
|| document.body;
Паттерн #3: Короткое замыкание (для действий)
javascript
// Выполнить действие, если условие ложно
isValid || showError(); // showError вызовется только если isValid falsy
Часть 3. && (И) - Оператор-пессимист
&& ищет первое ложное значение. Он движется слева направо и останавливается на первой лжи.
javascript
let result = value1 && value2 && value3;
// Алгоритм:
// 1. Проверить value1 → если falsy → вернуть value1
// 2. Если truthy → проверить value2 → если falsy → вернуть value2
// 3. Если все truthy → вернуть последнее значение
Примеры:
javascript
1 && 2 && 3 // 3 (всё truthy → последнее)
0 && 1 && 2 // 0 (первое falsy)
"hello" && null && "world" // null
true && "result" // "result"
Классические паттерны с &&
Паттерн #1: Безопасный доступ к свойствам (Guard)
javascript
// Без && - ошибка!
// let name = user.profile.name; // если user или profile нет → TypeError
// С && - безопасно
let name = user && user.profile && user.profile.name;
// Если что-то falsy на пути → вернется falsy, без ошибки
// Современное решение (ES2020) - optional chaining
let name = user?.profile?.name;
Паттерн #2: Условный вызов функции
javascript
// Вызвать функцию, только если объект существует
isLoggedIn && fetchUserData();
// Раньше писали так:
if (isLoggedIn) {
fetchUserData();
}
// && короче, но читается хуже
Паттерн #3: Рендеринг в React/JSX
jsx
// Классика React - показать компонент только если условие истинно
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
Часть 4. Короткое замыкание (Short-circuit evaluation)
Это магия, которая останавливает вычисления, как только результат известен.
javascript
// Для || - достаточно одной правды
true || anything(); // anything() НЕ вызовется!
// Для && - достаточно одной лжи
false && anything(); // anything() НЕ вызовется!
Реальный кейс - предотвращение ошибок:
javascript
// Плохо (вызовется всегда, даже если index вне границ)
if (index >= 0 && array[index].value) { }
// Хорошо - защита от ошибки
if (index >= 0 && array[index] && array[index].value) { }
// Если index < 0 → первое условие false → остальные не проверяются
Часть 5. Комбинации операторов (Приоритет имеет значение)
Приоритет: ! > && > || (как в математике: сначала умножение, потом сложение).
javascript
// Что выведет?
true || false && false; // true
// Почему? false && false выполнится первым (дает false)
// true || false → true
// С explicit скобками:
true || (false && false); // true
Правило: Если сомневаетесь - ставьте скобки. Код станет понятнее.
javascript
// Понятно даже новичку
if ((age >= 18 && hasLicense) || isSupervisor) {
driveCar();
}
Часть 6. Сравнение с другими языками (почему JS особенный)
В Python, Ruby, Java логические операторы возвращают boolean. В JavaScript - оригинальное значение.
javascript
// Python:
// "hello" or "world" → "hello" (но в булевом контексте True)
// JavaScript:
"hello" || "world" // "hello" (возвращает строку!)
Зачем это сделано? Для гибкости. Вы можете написать:
javascript
let port = config.port || 3000; // config.port может быть числом
// port будет числом, а не true/false
Часть 7. Подводные камни (или "Почему мой код не работает")
Камень #1: || с falsy-значениями
javascript
let count = 0 || 5; // 5 (0 - falsy, но это валидное число!)
let text = "" || "default"; // "default" (пустая строка — falsy)
// Решение: nullish coalescing (??)
let count = 0 ?? 5; // 0
let text = "" ?? "default"; // "" (пустая строка не заменяется)
Камень #2: && с числами
javascript
let result = 5 && 10; // 10 (не true!)
if (result === true) { } // Никогда не сработает
// Если нужен boolean - используйте !!
let boolResult = !!(5 && 10); // true
Камень #3: Приоритет с присваиванием
javascript
// Что делает этот код?
let x = 5 || 10; // x = 5 (всё ок)
// А это?
let y = 5 || 10 && 20; // y = 5 (&& выполнился раньше, но || нашел 5)
// А это ловушка!
let z = 0 || 5 && 10; // z = 10 (5 && 10 = 10, 0 || 10 = 10)
Часть 8. Реальные паттерны из продакшена
Паттерн #1: Цепочка проверок (валидация форм)
javascript
function validateForm(data) {
return data.name
&& data.email.includes('@')
&& data.age >= 18
&& data.agreeToTerms;
// Вернет первое falsy или последнее truthy
}
if (validateForm(formData) === false) {
showError();
}
Паттерн #2: Ленивая загрузка (memoization)
javascript
let cache = null;
function getData() {
return cache || (cache = fetchData());
// Если cache пуст → выполнится fetchData() и результат запишется в cache
}
Паттерн #3: Полифиллы (старый способ)
javascript
// Если window.Promise не существует - создать свою реализацию
window.Promise = window.Promise || customPromiseImplementation;
Паттерн #4: Условный middleware (Express.js)
javascript
app.use(
isProduction && require('express-sslify').HTTPS({ trustProtoHeader: true })
);
// В dev-режиме isProduction false → в middleware попадет false → Express его проигнорирует
Часть 9. Современные альтернативы (ES2020+)
Оператор ?? (Nullish Coalescing)
Заменяет || для случаев, когда важны null и undefined, а не все falsy.
javascript
let value = input ?? "default";
// input = null → "default"
// input = undefined → "default"
// input = 0 → 0 (не заменяет!)
// input = "" → "" (не заменяет!)
Оператор ?. (Optional Chaining)
Заменяет цепочки && для безопасного доступа.
javascript
// Старый способ
let city = user && user.address && user.address.city;
// Новый способ
let city = user?.address?.city;
Часть 10. Таблица истины (шпаргалка)
Выражение Результат Тип результата
!value true/false boolean
!!value true/false boolean
truthy || anything truthy оригинальный тип
falsy || value2 value2 оригинальный тип
falsy && anything falsy оригинальный тип
truthy && value2 value2 оригинальный тип
truthy || falsy && truthy truthy (&& выше приоритет)
Итог: Манифест логических операторов
- ! всегда возвращает boolean - используйте для инверсии.
- !! приводит к boolean - явно, понятно, безопасно.
- || ищет первую правду - отлично для значений по умолчанию (но осторожно с falsy).
- && ищет первую ложь - идеален для guard-выражений.
- Короткое замыкание - мощный инструмент, но не злоупотребляйте им для выполнения действий (if читается лучше).
- Приоритет: ! > && > || - ставьте скобки для ясности.
- Современные альтернативы: ?? и ?. - используйте их вместо || и цепочек && в новых проектах.
Финальный тест (проверьте себя):
javascript
console.log(0 || 1 && 2); // ?
console.log(null || undefined || 5); // ?
console.log("" && "hello" && 42); // ?
console.log(!!(false || true)); // ?
console.log(1 && 0 && 3); // ?
Ответы: 2, 5, "", true, 0.
Логические операторы в JavaScript - это не просто "правда или ложь". Это мощный механизм управления потоком, который позволяет писать короткий, выразительный и эффективный код. Но с великой силой приходит великая ответственность. Используйте их с умом, и ваш код будет и красивым, и понятным.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Спасители от ноля: Как ?? и ??= спасли миллионы проверок (и почему || больше не нужен)
Вы знаете эту боль. Вы пишете let count = value || 10, а потом обнаруживаете, что value = 0 - абсолютно нормальное значение, но ваш код заменил его на 10. И вы вздыхаете. И добавляете еще одну проверку.
Встречайте героев ES2020: оператор нулевого слияния ?? и его агрессивный брат ??=. Они пришли, чтобы раз и навсегда решить проблему "а это действительно отсутствие значения или просто ноль?"
Часть 1. Проблема, о которой молчат учебники
Долгие годы разработчики использовали || для значений по умолчанию:
javascript
let name = userName || "Гость";
let port = config.port || 3000;
let count = itemsCount || 1;
И всё было... почти хорошо. До тех пор, пока не пришли эти проклятые falsy-значения:
javascript
let count = 0 || 10; // 10 (хотя 0 - валидное число!)
let text = "" || "default"; // "default" (пустая строка - валидное значение!)
let isActive = false || true; // true (false - валидный boolean!)
Проблема: || проверяет на любое falsy (0, "", false, null, undefined, NaN). Но часто нам нужно заменить только null и undefined - случаи "реального отсутствия".
И тогда появился он.
Часть 2. ?? - Оператор нулевого слияния (Nullish Coalescing)
?? возвращает правую часть ТОЛЬКО если левая часть - null или undefined. Во всех остальных случаях - левую.
javascript
let result = value ?? defaultValue;
Правило: ?? проверяет на "nullish" (null или undefined). Всё остальное проходит.
Таблица истины для ??
Левая часть Результат
null правая часть
undefined правая часть
00 (не заменяет!)
"" "" (не заменяет!)
false false (не заменяет!)
NaN NaN (не заменяет!)
"hello" "hello"
[] []
{} {}
Примеры из реальной жизни
javascript
// Числа
let count = 0 ?? 10; // 0 (сохраняем ноль!)
let price = null ?? 100; // 100 (действительно нет значения)
// Строки
let name = "" ?? "Аноним"; // "" (пустая строка - ок)
let nickname = undefined ?? "Гость"; // "Гость"
// Булевы значения
let isVerified = false ?? true; // false (сохраняем false!)
let hasAccess = null ?? false; // false
// Объекты
let config = {} ?? defaultConfig; // {} (пустой объект - ок)
let settings = null ?? defaultSettings; // defaultSettings
Часть 3. ?? vs || - Битва титанов
Давайте сравним на реальных кейсах:
javascript
// Кейс 1: Ноль как валидное значение
function setVolume(level) {
// Плохо с ||
let volume = level || 50; // level = 0 → 50 (звук не выключить!)
// Хорошо с ??
let volume = level ?? 50; // level = 0 → 0 (тишина)
}
// Кейс 2: Пустая строка как валидное значение
function setUsername(name) {
// Плохо с ||
let displayName = name || "User"; // name = "" → "User"
// Хорошо с ??
let displayName = name ?? "User"; // name = "" → "" (пустое имя — ок)
}
// Кейс 3: false как валидное значение
function setFeatureFlag(flag) {
// Плохо с ||
let enabled = flag || true; // flag = false → true (не отключить!)
// Хорошо с ??
let enabled = flag ?? true; // flag = false → false
}
Когда использовать ||? Только когда вы действительно хотите заменить ВСЕ falsy-значения (включая 0, "", false).
javascript
// Правильное использование ||
let theme = userTheme || "light"; // Если userTheme = "" → light (ок, пустая тема не нужна)
let limit = userLimit || 10; // Если userLimit = 0 → 10 (ок, лимит 0 не имеет смысла)
Часть 4. ??= - Оператор нулевого присваивания (Nullish Assignment)
Если ?? проверяет и возвращает, то ??= присваивает. Это логическое присваивание для null и undefined.
javascript
// Вместо этого:
if (user.name === null || user.name === undefined) {
user.name = "Аноним";
}
// Можно так:
user.name ??= "Аноним";
Как это работает: ??= присваивает правую часть левой, ТОЛЬКО если левая часть - null или undefined.
Примеры
javascript
// Объекты
let config = {};
config.port ??= 3000; // config.port = 3000 (было undefined)
config.host ??= "localhost"; // config.host = "localhost"
config.port ??= 8080; // config.port = 3000 (уже есть значение)
// Массивы
let data = [1, 2, 3];
data[5] ??= "default"; // data[5] = "default" (индекс 5 не существовал)
data[0] ??= "new"; // data[0] = 1 (уже есть значение)
// Переменные
let value;
value ??= 42; // value = 42
value ??= 100; // value = 42 (не изменилось)
let count = 0;
count ??= 10; // count = 0 (0 не null/undefined)
Сравнение всех операторов присваивания
javascript
let a = null;
let b = 0;
// OR присваивание (||=) - для всех falsy
a ||= "default"; // a = "default"
b ||= 10; // b = 10 (0 → falsy → заменяется!)
// Nullish присваивание (??=) - только для null/undefined
a ??= "default"; // a = "default"
b ??= 10; // b = 0 (не заменяется!)
// AND присваивание (&&=) - если truthy
let c = 5;
c &&= 10; // c = 10 (5 truthy → присвоить 10)
let d = null;
d &&= 10; // d = null (не присваивается)
Часть 5. Подводные камни (обязательно к прочтению!)
Камень #1: Нельзя использовать ?? с && или || без скобок
javascript
// ОШИБКА! SyntaxError
let result = null || undefined ?? "default";
// Правильно - со скобками
let result = (null || undefined) ?? "default"; // "default"
// Или пересмотрите логику
let result = null ?? undefined ?? "default"; // "default"
Почему? Приоритет ?? и ||/&& специально сделан неоднозначным, чтобы заставить вас думать.
Камень #2: Цепочки ?? работают слева направо
javascript
let value = null ?? undefined ?? 0 ?? 42; // 0 (первый не-nullish)
// null → пропуск, undefined → пропуск, 0 → стоп
Камень #3: ??= не возвращает значение (в отличие от обычного =)
javascript
let x;
let y = x ??= 5; // y = undefined (??= возвращает undefined!)
console.log(y); // undefined
// А если так:
let a;
let b = (a ??= 5); // b = 5 (скобки не помогают — всё равно undefined)
// Лучше делать в два шага:
let c;
c ??= 10;
let d = c; // d = 10
Часть 6. Реальные паттерны из продакшена
Паттерн #1: Инициализация конфигов
javascript
class AppConfig {
constructor(options) {
this.port = options.port ?? 3000;
this.host = options.host ?? "localhost";
this.ssl = options.ssl ?? false; // false - валидное значение!
this.maxConnections = options.maxConnections ?? 100;
}
}
// Теперь можно передать 0, false, "" и они сохранятся
const config = new AppConfig({ port: 0, ssl: false });
console.log(config.port); // 0 (а не 3000!)
Паттерн #2: Ленивая инициализация с кешем
javascript
let cache = null;
function getData() {
// Старый способ (с ||)
// return cache || (cache = fetchData()); // если cache = 0 - беда
// Новый способ
return cache ?? (cache = fetchData());
}
// Или еще короче с ??=
function getData() {
cache ??= fetchData();
return cache;
}
Паттерн #3: Безопасная работа с DOM
javascript
function getElement(id) {
let element = document.getElementById(id);
// Если элемент не найден - создаем
element ??= createFallbackElement(id);
return element;
}
Паттерн #4: Работа с form values
javascript
function getFormData(form) {
return {
name: form.name.value ?? "", // пустая строка - ок
age: form.age.valueAsNumber ?? 0, // 0 - валидный возраст
newsletter: form.newsletter.checked ?? false, // false - не подписан
comment: form.comment.value ?? null // null - нет комментария
};
}
Паттерн #5: Мемоизация с сохранением falsy
javascript
const cache = new Map();
function fibonacci(n) {
// Старый способ (не работает с 0)
// if (!cache.has(n)) cache.set(n, computeFib(n));
// Новый способ
cache.get(n) ??= computeFib(n); // 0 сохранится!
return cache.get(n);
}
function computeFib(n) {
if (n <= 1) return n; // может вернуть 0!
return fibonacci(n - 1) + fibonacci(n - 2);
}
Часть 7. ?? и опциональная цепочка ?. - Неразлучная пара
Эти операторы созданы друг для друга:
javascript
// Вместе они творят магию
let city = user?.address?.city ?? "Город не указан";
// Если user или address или city - null/undefined → "Город не указан"
// Если city = "" → "" (пустая строка не заменяется!)
// Реальный кейс - API-ответы
const userData = {
profile: {
stats: {
visits: 0 // ноль посещений - валидное значение!
}
}
};
// Без ??
let visits = userData.profile.stats.visits || 1; // 1 (потеряли ноль!)
// С ??
let visits = userData.profile.stats.visits ?? 1; // 0 (сохранили!)
Часть 8. Браузерная поддержка (спойлер: отличная)
?? и ??= работают во всех современных браузерах:
- Chrome 80+
- Firefox 72+
- Safari 13.1+
- Edge 80+
Для старых браузеров (IE11) - транспиляция через Babel.
Итог: Манифест нулевого слияния
- ?? - для значений по умолчанию если 0, "", false - валидные значения.
- || - только когда вы хотите заменить ВСЕ falsy (включая ноль и пустую строку).
- ??= - для ленивой инициализации переменных и свойств.
- ?? + ?. = любовь - используйте вместе для безопасного доступа к данным.
- Никогда не смешивайте ?? с || или && без скобок - получите SyntaxError.
Финальный тест (проверьте понимание):
javascript
// Что выведет?
console.log(0 ?? 1); // ?
console.log(null ?? undefined ?? 5 ?? 10); // ?
console.log("" ?? "default"); // ?
console.log(false ?? true); // ?
let x = 5;
x ??= 10;
console.log(x); // ?
let y = null;
y ??= 20;
console.log(y); // ?
let obj = { count: 0 };
obj.count ??= 100;
console.log(obj.count); // ?
Ответы: 0, 5, "", false, 5, 20, 0.
Операторы нулевого слияния - это не просто синтаксический сахар. Это признание того, что разработчики годами боролись с проблемой различения "отсутствия значения" и "нулевого значения". Теперь у нас есть правильный инструмент для этой задачи. Используйте ?? и ??= - ваш код скажет вам спасибо.
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------