Валерий Шестернин
В JavaScript операторы играют ключевую роль в выполнении различных операций и управлении данными. От арифметических операторов, позволяющих производить математические вычисления, до логических, позволяющих проверять условия, операторы являются мощными инструментами для создания эффективного и гибкого кода. В этой статье мы рассмотрим основные типы операторов в JavaScript и их применение, а также предоставим примеры использования операторов в реальных ситуациях.
Арифметические операторы
Операторы в JavaScript делятся на два основных типа: унарные и бинарные (есть еще тернарный оператор, но он всего один и о нем немного позже). Отличие между ними в том, что унарные работают только с одним операндом (примитивом или выражением), а бинарный с двумя или более. Проще всего это продемонстрировать на операторе “+
”. В бинарном виде он складывает значения. При этом значениями могут быть не только числа, но и строки и в случае, если один из операндом строка - второй тоже будет преобразован в строку, а в унарном - пытается преобразовать строку в число. При этом унарный и бинарный плюс можно комбинировать:
console.log(1 + 2); //число 3
//бинароный плюс с числами
console.log("1" + "2"); //12 строкой
//банрный плюс со строками
console.log(1 + "2"); //12 строкой
//бинарный плюс со строкой и числом
console.log(+"2"); //число 2
//унареый плюс со строкой
console.log(+"строка без цифр"); //NaN
//если в троке нет цифр, вернет NaN
console.log(1 + +"2");//число 3
//комбинация бинарного и унарного плюса
Аналогично работают унарный и бинарный минусы за тем лишь исключением, что унарный плюс перед числом не делает ничего, а минус изменяет знак числа.console.log(-"-1");//число 1
console.log(+"-1");//число -1
В JavaScript существует еще несколько математических операторов:
- Умножение “
*
” - бинарный оператор, который умножает первый операнд на второй. - Возведение в степень “
**
” бинарный оператор, который возводит первый операнд в степень, указанную во втором. - Деление “
/
” бинарный оператор, который делит первый операнд на второй. - Остаток от деления “
%
” бинарный операнд, который возвращает остаток при делении нацело первого операнда на втрой. Часто используется для нахождения четных и нечетных чисел или кратных чисел.
При использовании этих операторов оба операнда будут приведены к числу.
console.log(5 * "2"); //число 10
console.log("5" ** "2"); //число 25
console.log("5" / 2); //число 2.5
console.log("5" % "2"); //число 1
Кроме того в JavaScript есть еще два унарных математических оператора: “`++`” инкремент и “`—`” декремент. Это просто синтаксический сахар, заменяющий прибавление или отнимание единицы. Пишутся они до или после операнда без пробела. Операндом могут быть только переменные, значения которых будут приведены к числу. При этом есть разница в том где они указаны. Оба вида записи изменяют значение переменной, но при указании до переменной оператор возвращает измененное значение, а при указании после - исходное.let counter1 = 0;
console.log(++counter1); //1
let counter2 = "0";
console.log(counter2++); //0
//обе переменные были увеличены на 1
console.log(counter1); //1
console.log(counter2); //1
Операторы сравнения
Логические операторы в JavaScript следуют следующим правилам:
- ссылочные типы данный сравниваются по ссылке, а не по значению. Т.е. два массива с одинаковыми значениями, объекта с одинаковыми полями и т.д. не будут равны друг другу, а ссылки на них - да.
- Строки сравниваются посимвольно используя для сравнения каждого символа кодировку Unicode (фактически сравниваются не сами символы, а их код в кодировке).
- При сравнении разных примитивных типов данных они приводятся к числу.
Их можно разделить на строгие и не строгие. Всего существует шесть “нестрогих” операторов сравнения:
- “
>
” больше и “<
” меньше - возвращает результат сравнения первого операнда со вторым. - “
> =
” больше или равно и “< =
” меньше или равно - то же, что предыдущие, но возвращают true и если операнды равны. - “
==
" равенство по значению - возвращает true, если значения операндов равны. - “
! =
” неравенство по значению - наоборот вернет true только если значения не равны.
console.log(1 > "1"); //false
console.log(1 >= "1"); //true
console.log(1 == "1"); //true
console.log(1 != "1"); //false
const a = [1, 2]; //массив это ссылочный тип данных
console.log(a == [1, 2]); // false
//поэтому сравнение его с лругим массивом всегда вернет false
const b = a;
console.log(a == b); //true
//обе переменные ссылаются на один массив и сравнение вернет true
В реальных проектах равенство и неравенство по значению применяется очень редко из-за того что они могут возвращать true при сравнении разных типов данных. Вместо них рекомендуется использовать “строгие” варианты операторов “`===`” для равенства и “`! ==`” для неравенства. Эти операторы сравнивают не только значения, но и типы данных операндов.console.log(1 == "1"); //true
console.log(1 === "1"); //false
console.log(1 != "1"); //false
console.log(1 !== "1"); //true
Хотя я и писал выше, что нестрогое сравниваемые значения приводятся к числам, есть исключения для null и undefined. Их сравнение с нулем дает странный, на первый взгляд результат:console.log(null > 0); //false
console.log(null == 0); //false
console.log(null >= 0); //true
console.log(undefined > 0); //false
console.log(undefined < 0); //false
console.log(undefined == 0); //false
Null приводится к числу со значением 0 только при сравнении через операторы `≤` b `≥`, а в остальных случаях остается собой. Undefined при любом сравнении выдает false потому что при приведении к числу возвращает NaN. При этом нестрогое сравнение null и undefined вернет true.
Логические операторы
Существует 4 логических оператора:
- “
||
” логическое “ИЛИ”- бинарный оператор, который возвращает первое истинное значение т.е. проходится по всем операндам, проверяя их на преобразование в булево значение и возвращает первый операнд из цепочки, который при преобразовании в булево значение будет равен true. Если все значения ложные - возвращает последнее. Часто используется для записи условий с диапазонами доступных значений. ts function check(hour) {//задаем в условиях часы работы офиса if (hour >= 8 || hour <= 12 || hour >= 13 || hour <= 17) { return "open";//если переданое значение соответвтвуе одному из неравенств } else { return "closed";//если не соответствует ни одному }}
“&&
” логическо “И” - бинарный операнд, который возвращает первое ложное значение или, если такого нет, возвращает последний операнд. Часто используется для проверки выполнения нескольких условий.ts const visitDateTime = { time: 12, dayOfWeek: "Monday" }; function check(dateTime) { if (dateTime.time >= 10 && dateTime.dayOfWeek !== "Sunday") { //если визит назначен не раньще 10 часов и не в всокресенье return "confirmed";//при выполнении обоих условий } else { return "unconfirmed";//при невыполнении хотя бы одного условия } }
“??
” оператор нулевого слияния - возвращает первое определенное (не равное null или undefined) значение или , если такого нет, возвращает последний операнд. Часто используется для задания значения по умолчанию.ts let first; //значение неопределено let second = undefined; // явно указан undefined let third = null; //явно указан null let fourth = "fourth"; // любое другое значение кроме undefined или null const res = first ?? second ?? third ?? fourth; console.log(res); //fourth //часто используется для установки значений по умолчанию let role; const userRole = role ?? "user"; console.log(userRole); //user
“!
” логическое “НЕ” - унарный оператор который приводит операнд к виду булева значения и меняет его на противоположное. Часто используется для создания проверки на отсутствие каких-то данных или изменение переменных, содержащих булевы значения.
const userData = ""; //данные не заполнены или не пришли
if (!userData) {
console.log("Введите данные!");
}
//берет пустую строку, которая после приведения к булеву
// значению равна false и меняет его на true
//т.е. условие в if() сработает
let isReady = false;
isReady = !isReady;//изменяет значение на противоположное
console.log(isReady); //true
Операторы присваивания
Кроме обычного оператора присваивания (”=
”) в JavaScript существуют бинарные операторы присваивания с операцией и операторы логического присваивания. Первые позволяют вместо простого присваивания переменной нового значения произвести операцию над его текущим значением. Синтаксис операторов присваивания с операцией объединяет синтаксис оператора нужной арифметической операции и простого присваивания (”*=
” - присваивание с умножением, “+=
” - присваивание со сложением и т.д.). Его вторым оперантом могут быть как числа, так и строки или переменные их содержащие.
let a = 2;
let b = 4;
b += 1; //b = 5 (5+1)
b *= a; //b = 10 (5*2)
Операторы логического присваивания ”`||=`” - присвоение через логическое “ИЛИ”, “`&&=`" - присвоение через логическое “И” и “`??=`” - оператор нулевого присвоения ведут себя схоже со своими логическими собратьями, но вместо первого операнда используют текущее значение переменной.const userData1 = { name: "", role: "user", age: undefined };
userData1.name ||= "John"; //поле имя имело ложное значение и будет изменено
userData1.role ||= "admin"; //роль не была ложным значением и не будет изменена
userData1.age ||= 22; //возраст был ложным значением и будет изменен
console.log(userData1); //{ name: 'John', role: 'user', age: 22 }
const userData2 = { name: "", role: "user", age: undefined };
userData2.name &&= "John"; //поле имя имело ложное значение и не будет изменено
userData2.role &&= "admin"; //роль не была ложным значением и будет изменена
userData2.age &&= 22; //возраст был ложным значением и не будет изменен
console.log(userData2); //{ name: '', role: 'admin', age: undefined }
const userData3 = { name: "", role: "user", age: undefined };
userData3.name ??= "John"; //поле имя не равно ни null ни undefined и не изменится
userData3.role ??= "admin"; //роль не равна ни null ни undefined и не изменится
userData3.age ??= 22; //возраст равен undefined и будет изменен
console.log(userData3); //{ name: '', role: 'user', age: 22 }
Тернарный оператор
Единственным оператором в JavaScript, который принимает три операнда является тернарный оператор. Он принимает условие и два выражения (условие ? выражение1 : выражение2
), после чего возвращает первое выражение, если условие истинно или второе, если условие ложно.
const condition = 1;
console.log(condition ? "first" : "second");//first
//условие истино и вернется первое выражение
condition = 0
console.log(condition ? "first" : "second");//second
//условие ложно и вернется второе выражение
Операторы доступа к свойствам объектов и optional chaining
Так же в JavaScript операторами считаются точка при обращении к свойствам объектов или квадратные скобки при обращении к элементам массивов. Кроме этих операторов существует оператор опциональной цепочки (optional chaining) ”?.
", который позволяет обратиться к свойству объекта только при его наличии не ломая исполнение кода. При этом его можно использовать и для обращения через квадратные скобки или вызове функции, являющейся свойством объекта.
const user1 = { name: "John" };
const usersDogName = user1.pets.dog.name;
console.log(dog); //TypeError: Cannot read properties of undefined (reading 'dog')
const usersCatName = user1.pets?.cat.name;
console.log(usersCatName); //undefined
//обращение через квадратные скобки
const user2 = null;
console.log(user2[name]); //ReferenceError: name is not defined
console.log(user2?.[name]); //undefined
//обращение к функции
const someFuncs = {
foo() {
console.log("foo");
},
};
someFuncs.bar(); //TypeError: someFuncs.bar is not a function
someFuncs.bar?.(); //гтчего не произойдет
Оператор “запятая”
Одним из самых редко используемых операторов является запятая. Она похожа на бинарные логические операторы, но всегда возвращает последнее значение. Используется данный оператор в основном в библиотеках для сокращения кода и записи нескольких операций в одну строку.
const a = (1, 2, 3);
console.log(a); //3
const myArr = [
//массив из 10 элементов, каждый элемент
//которого тоже массив из 10 элементов
];
for (let i = 0, j = 9; i <= 9; i++, j--) {
//такой цикл пройдет массив по диагонали
console.log(myArr[i][j]);
}
let a = 1,b = 2,c = 3,d = 4;
//объявление нескольких переменных в одну строку
Побитовые операторы
Побитовые операторы в JavaScript редко используются в обычной разработке и требуют дополнительных знаний и навыков. Они работают на уровне отдельных битов числа. Их можно использовать для работы с двоичными представлениями чисел. Они могут быть особенно полезны при работе с низкоуровневой графикой, сетевыми протоколами и криптографией.
Существует семь побитовых операторов:
- “
&
” побитовое “И” - бинарный оператор, который возвращает число, состоящее из битов, которые равны 1 у обоих чисел. Например, если a = 1011 и b = 1101, то a & b = 1001. - “
|
” побитовое “ИЛИ” - бинарный оператор, который возвращает число, состоящее из битов, которые равны 1 хотя бы у одного из чисел. Например, если a = 1011 и b = 1101, то a | b = 1111. - “
^
” побитовое “ИСКЛЮЧИТЕЛЬНОЕ ИЛИ” - бинарный оператор, который возвращает число, состоящее из битов, которые равны 1 только у одного из чисел. Например, если a = 1011 и b = 1101, то a ^ b = 0110. - “
~
” побитовое “НЕ” - унарный оператор, который возвращает инвертированное число, т.е. число, где все биты перевернуты. Если a = 1011, то ~a = 0100. - “
<<
” и “>>
” левый и правый сдвиг - бинарные операторы, которые сдвигают биты числа a на b позиций влево или вправо соответственно, добавляя нули справа. Это эквивалентно умножению числа на 2(при левом сдвиге), возведённое в степень b или делению числа на 2(для правого сдвига), возведенное в степень b. - “
>>>
” правый сдвиг с заполнением нулями - бинарный оператор, который действует как обычный правый сдвиг, но слева добавляются нули, а в отрицательных числах отбрасывается знак.
Следует отметить, что все числа сначала преобразуются в 32-битные перед применением операции. Результат также представляется как 32-битное целое. Для сокращения записи пример ниже будет представлен 4-битной виде.
const a = 12; // в двоичной системе: 1100
const b = 15; // в двоичной системе: 1111
console.log(a & b); // результат: 12 (в двоичной системе: 1100)
const a = 12; // в двоичной системе: 1100
const b = 15; // в двоичной системе: 1111
console.log(a | b); // результат: 15 (в двоичной системе: 1111)
const a = 12; // в двоичной системе: 1100
const b = 15; // в двоичной системе: 1111
console.log(a ^ b); // результат: 3 (в двоичной системе: 0011)
const a = 12; // в двоичной системе: 1100
console.log(~a); // результат: -13
// Причина в том, что в компьютерах числа хранятся в дополнительном коде,
// поэтому результат операции ~a будет равен -(a + 1).
const a = 3; // в двоичной системе: 11
console.log(a << 2); // результат: 12 (в двоичной системе: 1100)
// Это эквивалентно умножению числа 3 на 2 в степени 2 (3 * (2**2) = 12)
const a = 12; // в двоичной системе: 1100
console.log(a >> 2); // результат: 3 (в двоичной системе: 11)
// Это эквивалентно делению числа 12 на 2 в степени 2 (12 / (2**2) = 3)
const a = -12; // в двоичной системе: 1100
console.log(a >>> 2); // результат: 1073741821
// Этот оператор сдвигает все биты кправо и заполняет биты слева нулями.
// Это отличается от >> тем, что >> сохраняет знак числа,
// а >>> игнорирует знак и всегда добавляет нули слева.
Приоритет операторов и их группировка
Операторы имеют свои приоритеты исполнения, аналогично с алгебраическими операциями. Полную таблицу приоритизации можно посмотреть на MDN, но заучивать ее не стоит, главное запомнить что унарные операторы выше по приоритету, чем их бинарные аналоги, а для контроля за порядком исполнения операторов следует использовать группировку скобками, которая имеет максимальный приоритет.
console.log(1 + +"2"); //число 3
//сначала сработал унарный плюс, а потом бинарный
console.log(+(1 + "2")); //число 12
// если изменить порядок срабатывания операторов с помощью
//группировки скобками мы получим другой результат
Заключение:
Операторы играют важную роль в языке JavaScript, обеспечивая управление данными и выполнение операций. Понимание и умение использовать операторы поможет разработчикам создавать более эффективный и функциональный код на JavaScript. 
Карта развития разработчика
Получите полную карту развития разработчика по всем направлениям: frontend, backend, devops, mobile
Комментарии
0