Примечание
ЭТО АРХИВНАЯ ВЕРСИЯ КУРСА!
Материалы предназначаются для пересдающих дисциплину "ОП.04 - Основы алгоритмизации и программирования" в соответствии с учебными планами СПО годов набора ДО 2023-го.
Материалы были перенесены со старого сайта с минимальной доработкой, поэтому не все возможности курса могут работать как ожидается, где-то может слететь форматирование.
Домашние задания в рамках курса проверяться не будут!
ОП.04 - 10 - Операторы, операции и выражения. Условия, их виды и комбинации
Код примера для практической работы
Операторы, операции и выражения
Для начала давайте разберёмся с терминологией.
Операция — конкретная программная инструкция, состоящая из оператора и хотя бы одного операнда.
Как видно из определения, чтобы его понять, нужно рассмотреть также понятия оператор и операнд.
Оператор — наименьшая автономная часть языка программирования, представляющая собой команду.
Многие операторы знакомы нам ещё со школы: сложение +, умножение *, вычитание -, деление /, и с одним мы уже познакомились когда проходили переменные, это оператор присваивания =.
Операнд — то, к чему применяется оператор.
Например, в умножении 5 * 2 есть два операнда: левый операнд равен 5, а правый операнд равен 2, при этом между ними стоит один оператор умножения *.
Унарным называется оператор, который применяется к одному операнду.
Например, оператор унарный минус - меняет знак числа на противоположный:
let x = 1;
console.log( x ); // 1
x = -x;
console.log( x ); // -1, применили унарный минус
Бинарным называется оператор, который применяется к двум операндам.
Тот же минус существует и в бинарной форме:
let x = 1, y = 3;
console.log( y - x ); // 2, бинарный минус вычитает значения
Формально, в последних примерах мы говорим о двух разных операторах, использующих один символ: оператор отрицания (унарный оператор, который обращает знак) и оператор вычитания (бинарный оператор, который вычитает одно число из другого).
[!INFO]
Часто в источниках используют и несколько более широкое понятие — выражение, под которым в информатике понимается комбинация значений, констант, переменных, операций и функций, которая может быть интерпретирована в соответствии с правилами конкретного языка. Интерпретация (выполнение) такого выражения приводит к вычислению некоторого значения (например, числа, строки или значения логического типа).
Математические операторы
В JavaScript поддерживаются следующие математические операторы:
- Сложение
+ - Вычитание
- - Умножение
* - Деление
/ - Взятие остатка от деления
% - Возведение в степень
**
Первые четыре оператора очевидны, а про % и ** стоит сказать несколько слов.
Взятие остатка %
Оператор взятия остатка %, несмотря на обозначение, никакого отношения к процентам не имеет.
Результат a % b — это остаток от целочисленного деления a на b.
Например:
console.log( 5 % 2 ); // 1, остаток от деления 5 на 2
console.log( 8 % 3 ); // 2, остаток от деления 8 на 3
Возведение в степень **
В выражении a ** b оператор возведения в степень умножает a на само себя b раз.
Например:
console.log( 2 ** 2 ); // 4 (2 умножено на себя 2 раза)
console.log( 2 ** 3 ); // 8 (2 * 2 * 2, 3 раза)
console.log( 2 ** 4 ); // 16 (2 * 2 * 2 * 2, 4 раза)
Математически, оператор работает и для нецелых чисел. Например, квадратный корень является возведением в степень 1/2:
console.log( 4 ** (1/2) ); // 2 (степень 1/2 эквивалентна взятию квадратного корня)
console.log( 4 ** (0.5) ); // 2 (то же справедливо и для десятичных дробей)
console.log( 8 ** (1/3) ); // 2 (степень 1/3 эквивалентна взятию кубического корня)
Сложение строк, конкатенация
Обычно при помощи плюса + складывают числа.
Но если бинарный оператор + применить к строкам, то он их объединяет в одну:
let s = "моя" + "строка";
console.log(s); // моястрока
Бинарный оператор
+применимо к строкам производит сложение строк, операцию которая называется конкатенацией.
Обратите внимание, если хотя бы один операнд является строкой, то второй будет также преобразован в строку.
Например:
console.log( '1' + 2 ); // "12"
console.log( 2 + '1' ); // "21"
Как видите, не важно, первый или второй операнд является строкой.
Вот пример посложнее:
console.log(2 + 2 + '1' ); // будет "41", а не "221"
Здесь операторы работают один за другим. Первый + складывает два числа и возвращает 4, затем следующий + объединяет результат со строкой, производя действие 4 + '1' = '41'.
Сложение и преобразование строк — это особенность бинарного плюса +. Другие арифметические операторы работают только с числами и всегда преобразуют операнды в числа.
Например, вычитание и деление:
console.log( 6 - '2' ); // 4, '2' приводится к числу
console.log( '6' / '2' ); // 3, оба операнда приводятся к числам
Приоритет операторов
В том случае, если в выражении есть несколько операторов — порядок их выполнения определяется приоритетом, или, другими словами, существует определённый порядок выполнения операторов. Из школы мы знаем, что умножение в выражении 1 + 2 * 2 выполнится раньше сложения. Это как раз и есть «приоритет». Говорят, что умножение имеет более высокий приоритет, чем сложение. Скобки важнее, чем приоритет, так что, если мы не удовлетворены порядком по умолчанию, мы можем использовать их, чтобы изменить приоритет. Например, написать (1 + 2) * 2.
В JavaScript много операторов. Каждый оператор имеет соответствующий номер приоритета. Тот, у кого это число больше — выполнится раньше. Если приоритет одинаковый, то порядок выполнения — слева направо.
Приоритеты всех основных оператором можно посмотреть в таблице (нет необходимости всё запоминать, обратите внимание, что приоритет унарных операторов выше, чем соответствующих бинарных).
Оператор присваивания
Давайте отметим, что в таблице приоритетов также есть оператор присваивания =. У него один из самых низких приоритетов: 2. Именно поэтому, когда переменной что-либо присваивают, например, x = 2 * 2 + 1, то сначала выполнится арифметика, а уже затем произойдёт присваивание = с сохранением результата в x.
let x = 2 * 2 + 1;
console.log( x ); // 5
Инкремент/декремент
Одной из наиболее частых числовых операций в программировании является увеличение или уменьшение на единицу.
Для этого существуют даже специальные операторы:
Инкремент
++увеличивает переменную на1.
Пример:
let counter = 2;
counter++; // работает как counter = counter + 1, просто запись короче
console.log( counter ); // 3
Декремент
--уменьшает переменную на1.
Пример:
let counter = 2;
counter--; // работает как counter = counter - 1, просто запись короче
console.log( counter ); // 1
[!WARNING]
Инкремент/декремент можно применить только к переменной. Попытка использовать его на значении типа5++, приведёт к ошибке.
Операторы сравнения
Многие операторы сравнения известны нам из математики.
В JavaScript они записываются так:
- Больше/меньше:
a > b,a < b. - Больше/меньше или равно:
a >= b,a <= b. - Равно:
a == b. Обратите внимание, для сравнения используется двойной знак равенства==. Один знак равенстваa = bозначал бы присваивание. - Не равно. В математике обозначается символом , но в JavaScript записывается как
a != b.
Все операторы сравнения возвращают значение логического типа.
true— означает «да», «верно», «истина».false— означает «нет», «неверно», «ложь».
Сравнение чисел
Например:
console.log( 2 > 1 ); // true (верно)
console.log( 2 == 1 ); // false (неверно)
console.log( 2 != 1 ); // true (верно)
Результат сравнения можно присвоить переменной, как и любое значение:
let result = 5 > 4; // результат сравнения присваивается переменной result
console.log( result ); // true
Сравнение строк
Чтобы определить, что одна строка больше другой, JavaScript использует «алфавитный» или «лексикографический» порядок.
Другими словами, строки сравниваются посимвольно.
Например:
console.log( 'Я' > 'А' ); // true
console.log( 'Коты' > 'Кода' ); // true
console.log( 'Сонный' > 'Сон' ); // true
Алгоритм сравнения двух строк довольно прост:
- Сначала сравниваются первые символы строк.
- Если первый символ первой строки больше (меньше), чем первый символ второй, то первая строка больше (меньше) второй. Сравнение завершено.
- Если первые символы равны, то таким же образом сравниваются уже вторые символы строк.
- Сравнение продолжается, пока не закончится одна из строк.
- Если обе строки заканчиваются одновременно, то они равны. Иначе, большей считается более длинная строка.
В примерах выше сравнение 'Я' > 'А' завершится на первом шаге, тогда как строки 'Коты' и 'Кода' будут сравниваться посимвольно:
КравнаК.оравнао.тбольше, чемд. На этом сравнение заканчивается.- Результат: Первая строка больше.
[!INFO]
Используется кодировка Unicode, а не настоящий алфавит
Приведённый выше алгоритм сравнения похож на алгоритм, используемый в словарях и телефонных книгах, но между ними есть и различия. Например, в JavaScript имеет значение регистр символов. Заглавная буква"A"не равна строчной"a". Какая же из них больше? Строчная"a". Почему? Потому что строчные буквы имеют больший код во внутренней таблице кодирования, которую использует JavaScript (Unicode).
Сравнение разных типов
При сравнении значений разных типов JavaScript приводит каждое из них к числу.
Например:
console.log( '2' > 1 ); // true, строка '2' становится числом 2
console.log( '01' == 1 ); // true, строка '01' становится числом 1
Логическое значение true становится 1, а false — 0.
Например:
console.log( true == 1 ); // true
console.log( false == 0 ); // true
Строгое сравнение
Использование обычного сравнения == может вызывать проблемы.
Например, оно не отличает 0 от false:
console.log( 0 == false ); // true
Та же проблема с пустой строкой:
console.log( '' == false ); // true
Это происходит из-за того, что операнды разных типов преобразуются оператором == к числу. В итоге, и пустая строка, и false становятся нулём. Как же тогда отличать 0 от false?
Оператор строгого равенства === проверяет равенство без приведения типов. Другими словами, если a и b имеют разные типы, то проверка a === b немедленно возвращает false без попытки их преобразования.
Давайте проверим:
console.log( 0 === false ); // false, так как сравниваются разные типы
Ещё есть оператор строгого неравенства !==, аналогичный !=.
Оператор строгого равенства делает код более очевидным и оставляет меньше места для ошибок.
Сравнение с null и undefined
Значения
nullиundefinedравны==друг другу и не равны любому другому значению.
При строгом равенстве ===
Эти значения различны, так как различны их типы.
console.log( null === undefined ); // false
При нестрогом равенстве ==
Эти значения равны друг другу и не равны никаким другим значениям. Это специальное правило языка.
console.log( null == undefined ); // true
Поведение null и undefined при сравнении с другими значениями — особое. При использовании математических операторов и других операторов сравнения < > <= >=, значения null/undefined преобразуются к числам: null становится 0, а undefined — NaN.
Логические операторы
В JavaScript есть четыре логических оператора: || (ИЛИ), && (И) и ! (НЕ), ?? (Оператор нулевого слияния). В рамках данного курса оператор ?? мы рассматривать не будем.
Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип. Давайте рассмотрим их подробнее.
Если значение не логического типа, то оно к нему приводится в целях вычислений.
Оператор || (ИЛИ)
Оператор ИЛИ выглядит как двойной символ вертикальной черты:
result = a || b;
Традиционно в программировании ИЛИ предназначено для манипулирования булевыми значениями: в случае, если какой-либо из аргументов true, он вернёт true, в противоположной ситуации возвращается false.
Существует всего четыре возможные логические комбинации:
console.log( true || true ); // true
console.log( false || true ); // true
console.log( true || false ); // true
console.log( false || false ); // false
Оператор && (И)
Оператор И пишется как два амперсанда:
result = a && b;
В традиционном программировании И возвращает true, если оба аргумента истинны, а иначе — false.
Существует всего четыре возможные логические комбинации:
console.log( true && true ); // true
console.log( false && true ); // false
console.log( true && false ); // false
console.log( false && false ); // false
Приоритет оператора
&&больше, чем у||.
Оператор ! (НЕ)
Оператор НЕ представлен восклицательным знаком:
result = !value;
Оператор принимает один аргумент и выполняет следующие действия:
- Сначала приводит аргумент к логическому типу
true/false. - Затем возвращает противоположное значение.
Например:
console.log( !true ); // false
console.log( !0 ); // true
В частности, двойное НЕ !! используют для преобразования значений к логическому типу:
console.log( !!"непустая строка" ); // true
console.log( !!null ); // false
То есть первое НЕ преобразует значение в логическое значение и возвращает обратное, а второе НЕ снова инвертирует его. В конце мы имеем простое преобразование значения в логическое.
Есть немного более подробный способ сделать то же самое — встроенная функция Boolean которую мы рассматривали ранее когда говорили о преобразовании типов:
console.log( Boolean("non-empty string") ); // true
console.log( Boolean(null) ); // false
Приоритет НЕ
!является наивысшим из всех логических операторов, поэтому он всегда выполняется первым, перед&&или||.
Условия, их виды и комбинации
Иногда нам нужно выполнить различные действия в зависимости от условий. Для этого мы можем использовать инструкцию if и условный оператор ?, который также называют «тернарным оператором».
Инструкция if (ЕСЛИ)
Инструкция if(...) вычисляет условие в скобках и, если результат true, то выполняет блок кода.
Например:
let year = prompt('В каком году человек полетел в космос?', '');
if (year == 1961) alert( 'Именно так!' );
В примере выше, условие — это простая проверка на равенство (year == 1961), но оно может быть и гораздо более сложным.
Если мы хотим выполнить более одной инструкции, то нужно заключить блок кода в фигурные скобки:
let year = prompt('В каком году человек полетел в космос?', '');
if (year == 1961) {
alert( "Правильно!" );
alert( "Вы такой умный!" );
}
[!TIP]
Рекомендуется использовать фигурные скобки{}всегда, когда вы используете инструкциюif, даже если выполняется только одна команда. Это улучшает читаемость кода.
Инструкция if (…) вычисляет выражение в скобках и преобразует результат к логическому типу.
Давайте вспомним правила преобразования типов которые мы изучали ранее:
- Число
0, пустая строка"",null,undefinedиNaNстановятсяfalse. Из-за этого их называют «ложными» значениями или falsy. - Остальные значения становятся
true, поэтому их называют «правдивыми» значениями или truthy.
Таким образом, код при таком условии никогда не выполнится:
if (0) { // 0 is falsy
...
}
...а при таком — выполнится всегда:
if (1) { // 1 is truthy
...
}
Блок else (ИНАЧЕ)
Инструкция if может содержать необязательный блок else («иначе»). Он выполняется, когда условие ложно.
Например:
let year = prompt('В каком году человек полетел в космос?', '');
if (year == 1961) {
alert( 'Да вы знаток!' );
} else {
alert( 'А вот и неправильно!' ); // любое значение, кроме 1961
}
Несколько условий else if (ИНАЧЕ ЕСЛИ)
Иногда, нужно проверить несколько вариантов условия. Для этого используется блок else if.
Например:
let year = prompt('В каком году человек полетел в космос?', '');
if (year < 1961) {
alert( 'Это слишком рано...' );
} else if (year > 1961) {
alert( 'Это поздновато' );
} else if (year == 1961) {
alert( 'Верно!' );
} else {
alert( 'Что-то странное вы ввели...' );
}
В приведённом выше коде JavaScript сначала проверит year < 1961. Если это неверно, он переходит к следующему условию year > 1961. Если оно тоже ложно, тогда сработает проверка year == 1961, и если вдруг и она по какой-то причине не пройдет (например если будет введена строка с какими-то данными, например с фразой Я НЕ ЗНАЮ!), тогда сработает последний alert.
Блоков else if может быть и больше. Присутствие блока else не является обязательным.
[!WARNING]
Вне зависимости от того сколько блоковelse ifиспользуется в коде и есть ли блокelse, для того чтобы вся конструкция работала, должен быть один блок с изначальным условиемifс которого и начнется проверка. Кроме того, блокelseв наборе условий может быть только один и он всегда должен стоять самым последним.
Условный оператор ?
Иногда нам нужно определить переменную в зависимости от условия.
Например:
let accessAllowed;
let age = prompt('Сколько вам лет?', '');
if (age > 18) {
accessAllowed = true;
} else {
accessAllowed = false;
}
alert(accessAllowed);
Так называемый «условный» оператор позволяет нам сделать это более коротким и простым способом. Оператор представлен знаком вопроса ?. Его также называют «тернарный», так как этот оператор, единственный в своём роде, имеет три аргумента.
Синтаксис:
let result = условие ? значение_если_истина : значение_если_ложь;
Сначала вычисляется условие: если оно истинно, тогда возвращается значение_если_истина, в противном случае — значение_если_ложь.
Например:
let accessAllowed;
let age = prompt('Сколько вам лет?', '');
accessAllowed = (age > 18) ? true : false;
alert(accessAllowed);
Технически, мы можем опустить круглые скобки вокруг age > 18. Оператор имеет низкий приоритет, поэтому он выполняется после сравнения >.
[!TIP]
Рекомендуется использовать()всегда, когда вы используете оператор?. Это улучшает читаемость кода.
Что почитать по теме
- Современный учебник JavaScript - Базовые операторы, математика
- Современный учебник JavaScript - Операторы сравнения
- Современный учебник JavaScript - Условное ветвление: if, '?'
- Современный учебник JavaScript - Логические операторы
- W3Schools - JavaScript Operators
- W3Schools - JavaScript Comparison and Logical Operators
- W3Schools - JavaScript if, else, and else if