Демистифицирующие операторы JavaScript: что означает этот символ?


В этой статье мы рассмотрим операторы в JavaScript один за другим. Мы объясним их функции и продемонстрируем их использование, помогая вам понять их роль в построении более сложных выражений.
Содержаение
- Что такое операторы JAvaScript
- Несколько слов о терминологии
- Арифметические операторы
- Операторы присваивания
- Операторы сравнения
- Логические операторы
- Побитовые операторы
- Другие операторы
- Заключение
Что такое операторы JavaScript?
JavaScript, краеугольный камень современной веб-разработки, является надежным языком, полным многочисленных функций и конструкций. Среди них операторы (специальные символы, такие как +
, +=
, &&
или ...
) играют важную роль, позволяя нам выполнять различные типы вычислений и манипуляций с переменными и значениями.
Несмотря на свою важность, операторы иногда могут быть источником путаницы как для начинающих, так и для опытных программистов.
Найдите минутку, чтобы изучить этот фрагмент кода:
const x = 10, y = 20, z = 30;
console.log((x > y ? x : y) > z ? (x > y ? x : y) : z);
// WTF?
Не пугайтесь, если он покажется вам немного загадочным. К тому времени, как мы закончим, вы сможете точно понять, что он делает.
Несколько слов о терминологии
Прежде чем мы углубимся, давайте проясним пару терминов, которые мы будем использовать довольно часто:
-
Операнд - это элемент, с которым работают операторы. Если мы думаем об операторе как о своего рода действии, то операнд - это то, к чему применяется действие. Например, в выражении 5 + 3
+
является оператором (действием сложения), а 5 и 3 являются операндами — суммируемыми числами. В JavaScript операнды могут быть различных типов, таких как числа, строки, переменные или даже более сложные выражения. -
Принуждение - это процесс преобразования значения из одного примитивного типа в другой. Например, JavaScript может преобразовать число в строку или небулевое значение в логическое. Примитивными типами в JavaScript являются
String
,Number
,BigInt
,Boolean
,undefined
,Symbol
,null
. -
NaN
обозначает не число. Это специальное значениеNumber
типа, которое представляет недопустимое или непредставимое числовое значение. -
Истинные значения — это те, которые в логическом контексте оцениваются как
true
, в то время как ложные значения оцениваются какfalse
- с ложными значениями, равными0
,-0
,''
null
,undefined
,NaN
,BigInt(0)
.
По мере изучения операторов JavaScript мы увидим эти концепции в действии и лучше поймем, как они влияют на результаты наших операций.
Арифметические операторы
Арифметические операторы позволяют нам выполнять арифметические операции со значениями и преобразовывать данные. К наиболее часто используемым арифметическим операторам в JavaScript относятся сложение (+
), вычитание (-
), умножение (*
) и деление (/
). Помимо них, у нас также есть оператор modulus (%
), который возвращает остаток от операции деления, и операторы increment (++
) и decrement (--
), которые изменяют значение на единицу.
Сложение: +
Оператор сложения выполняет две разные операции: числовое сложение и конкатенацию строк. При вычислении выражений с использованием +
оператора JavaScript сначала приводит оба операнда к примитивным значениям. Как только это будет сделано, будут рассмотрены типы обоих операндов.
Если один операнд является строкой, другой операнд также преобразуется в строку, а затем две строки объединяются. Например:
'Hello, ' + 'World!' // Hello, World!
'The number is ' + 42 // 'The number is 42'
Если оба операнда имеют значение BigInts
, BigInt
выполняется сложение. A BigInt
- это специальный числовой тип, который может обрабатывать числа, большие, чем может обрабатывать стандартный Number
тип.
Но если один операнд является a BigInt
, а другой нет, JavaScript выдает TypeError
:
const num1 = BigInt(12345678901234567890);
const num2 = BigInt(12345678901234567890);
num1 + num2 // 24691357802469134336n
num1 + 1 // Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
Во всех остальных случаях оба операнда преобразуются в числа и выполняется числовое сложение. Например:
10 + 20 // 30
10 + true // 11 — true is converted to a value of 1
Имейте в виду, что JavaScript иногда имеет странное представление о том, как это выглядит:
1 + { a: 1 } // '1[object Object]'
В этом случае JavaScript попытался преобразовать объект { a: 1 }
в примитивное значение, но лучшее, что он мог сделать, это преобразовать его в строку [object Object]
, которая затем была объединена с числом 1.
Вычитание: -
Оператор вычитания в JavaScript прост в использовании: он используется для вычитания одного числа из другого. Как и оператор сложения, он также работает с BigInt
типом.
Если оба операнда являются числами или могут быть преобразованы в числа, JavaScript выполняет числовое вычитание:
10 - 3 // 7
'100' - 30 // 70
Если оба операнда являются BigInts
, JavaScript выполняет BigInt
вычитание:
const num1 = BigInt('9007199254740993');
const num2 = BigInt('3');
num1 - num2 // 9007199254740990n
Как и оператор сложения, вычитание также может привести к неожиданным результатам при использовании с не-числами. Например, если мы попытаемся вычесть что-то, что не может быть преобразовано в число, JavaScript вернет NaN
, что означает “Не число”.:
10 - 'Jim' // NaN
Умножение: *
Оператор умножения работает с числами и бигинтами.
Обычно мы будем перемножать числа:
10 * 5 // 50
Если оба операнда равны BigInts
, то выполняется BigInt
умножение:
const num1 = 9007199254740993n;
num1 * 2n // 18014398509481986n
Как и в случае с другими операторами, JavaScript пытается преобразовать нечисловые значения в числа. Если он не может этого сделать, он возвращает NaN
:
'100' * 30 // 3000
10 * 'Jim' // NaN
Деление: /
Оператор деления (/
) работает с числами и BigInts
почти так же, как +
, -
и *
. Сначала он преобразует оба операнда в числа.
Стандартное деление чисел:
10 / 2 // 5
10 / '2' // 5
При работе с BigInts
оператор деления ведет себя немного по-другому. Он выполняет деление и отбрасывает любой остаток, эффективно усекая результат до нуля:
const num = 10n;
num / 3n // 3n, not 3.333...n
Деление числа на ноль приведет к получению Infinity
, если только это не a BigInt
, и в этом случае оно выдает a RangeError
.
Если мы попытаемся разделить число на значение, которое не может быть преобразовано в число, JavaScript обычно вернет NaN
.
Модуль (остаток): %
Оператор модуля используется для нахождения остатка после деления одного числа на другое (известного как делимое и делитель). Этот арифметический оператор работает с числами и BigInts
.
Когда мы используем %
оператор, JavaScript сначала преобразует операнды в числа:
10 % 3 // 1
'10' % 3 // 1
Это потому, что три трижды превращается в десять (получается девять), а то, что остается (остаток), равно единице.
Обычный вариант использования этого оператора - проверить, является ли число четным или нечетным:
const isEven = num => num % 2 === 0;
isEven(1) // false
isEven(2) // true
Здесь используется функция со стрелкой и оператор тройного равенства, с которым мы познакомимся позже.
Оператор modulus имеет несколько особых случаев. Например, если один из операндов равен NaN
, если делимое равно Infinity
или если делитель равен 0
, операция возвращает значение NaN
.
С другой стороны, если делитель равен Infinity
или если делимое равно 0
, операция возвращает делимое.
Увеличение: ++
Оператор increment используется для увеличения значения переменной на 1. Он может применяться к операндам типа Number
или BigInt
, и его поведение может отличаться в зависимости от того, используется ли он в постфиксной или префиксной форме.
Приращение постфикса
Если оператор помещается после операнда (num++
), операция увеличения выполняется после возврата значения. В этом случае исходное значение переменной используется в текущем выражении, а значение переменной впоследствии увеличивается:
let num = 5;
const result = num++;
console.log(result); // 5
console.log(num); // 6
Увеличение префикса
Если оператор помещается перед операндом (++num
), операция увеличения выполняется перед возвращением значения. В этом случае сначала увеличивается значение переменной, а затем обновленное значение используется в текущем выражении:
let num = 5;
const result = ++num;
console.log(result); // 6
console.log(num); // 6
Уменьшение: --
Оператор уменьшения используется для уменьшения значения переменной на 1. Подобно оператору увеличения, он может применяться к операндам типа Number
или BigInt
. Поведение оператора уменьшения может варьироваться в зависимости от того, используется ли он в постфиксной или префиксной форме.
Постфиксное уменьшение
Когда оператор помещается после операнда (num--
), операция уменьшения выполняется после возврата значения. В этом случае исходное значение переменной используется в текущем выражении, а значение переменной впоследствии уменьшается:
let num = 5;
const result = num--;
console.log(result); // 5
console.log(num); // 4
Уменьшение префикса
Когда оператор помещается перед операндом (--num
), операция уменьшения выполняется перед возвращением значения. В этом случае значение переменной сначала уменьшается, а затем обновленное значение используется в текущем выражении:
let num = 5;
const result = --num;
console.log(result); // 4
console.log(num); // 4
Оператор уменьшения, как и оператор увеличения, может использоваться только с переменными, которые можно изменять:
const num = 5;
const result = num--; // Uncaught TypeError: Assignment to constant variable.
Разные арифметические операторы
В дополнение к операторам инкремента и декремента в JavaScript существуют другие арифметические операторы, о которых мы должны знать.
Оператор унарного отрицания (-
) используется для отрицания числового значения, изменяя его знак на противоположный. Например, -5
это было бы отрицанием числа 5
.
Оператор унарного плюса (+
) может использоваться для явного преобразования значения в число, что может быть полезно при работе со строковыми представлениями чисел. Например, +'10'
преобразует строку '10'
в число 10
:
const num = '10';
const res = +num; // unary operator converts String to Number
res // 10
Оператор возведения в степень (**
) используется для возведения числа в степень. Например, 2 ** 3
представляет собой 2, возведенное в степень 3, что приводит к 8.
Также важно отметить, что JavaScript следует правилам приоритета операторов, которые определяют порядок, в котором операторы вычисляются в выражении. Например, умножение и деление имеют более высокий приоритет, чем сложение и вычитание, поэтому они оцениваются первыми:
const result = 10 + 5 * 2; // Multiplication is evaluated first
console.log(result); // 20
Мы можем изменить порядок вычисления, используя оператор группировки ()
, который описан в разделе “Оператор группировки” ниже.
Операторы присваивания
Операторы присваивания используются для присвоения значений переменным. Они также предлагают краткий и эффективный способ обновления значения переменной на основе выражения или другого значения. В дополнение к базовому оператору присваивания (=
), JavaScript предоставляет составные операторы присваивания, которые объединяют арифметические или логические операции с присваиванием.
Присваивание: =
Этот оператор используется для присвоения значения переменной. Он позволяет нам сохранять значение в переменной, чтобы мы могли использовать его позже в нашем коде и ссылаться на него:
const num = 4; // Assign the value 4 to the variable num
const squared = num * num; // Assign the value 16 to the variable squared
Оператор присваивания присваивает значение в правой части оператора переменной в левой части.
Кроме того, =
оператор может быть связан цепочкой для присвоения одного и того же значения нескольким переменным в одной строке:
const a = b = c = 10; // Assign the value 10 to variables a, b, and c
console.log(a, b, c); // 10 10 10
Присваивание сложения: +=
Оператор присваивания сложения - это составной оператор, который выполняет операцию и присваивание за один шаг. В частности, он добавляет правый операнд к левому операнду, а затем присваивает результат левому операнду:
let num = 10;
num += 5 // 15
Этот оператор не ограничивается числами. Его также можно использовать для конкатенации строк:
let greeting = 'Hello, ';
greeting += 'World!' // 'Hello, World!'
Когда операнды не одного типа, JavaScript применяет те же правила приведения типов, которые мы видели ранее:
let greeting = 'Hello, ';
greeting += 42 // 'Hello, 42'
Присваивание вычитания: -=
Оператор присваивания вычитания - это еще один составной оператор, который выполняет операцию и присваивание за один шаг. Он вычитает правый операнд из левого операнда, а затем присваивает результат левому операнду:
let num = 10;
num -= 5 // 5
Как и другие операторы JavaScript, -=
выполняет приведение к типу, когда операнды не одного типа. Если операнд может быть преобразован в число, JavaScript сделает это:
let num = '10';
num -= 5 // num is now 5 (number), not '5' (string)
В противном случае результатом будет NaN
:
let name = 'Jim';
name -= 5 // NaN
Присваивание умножения: *=
Оператор присваивания умножения умножает левый операнд на правый операнд, а затем присваивает результат обратно левому операнду:
let num = 5;
num *= 3 // 15
Когда мы используем операнды разных типов, JavaScript попытается преобразовать нечисловые строковые операнды в числа:
let num = '5';
num *= 3 // num is now 15 (number), not '15' (string)
Если строковый операнд не может быть преобразован в число, результатом будет NaN
.
Присваивание деления: /=
Как и его собратья, оператор присваивания деления выполняет операцию над двумя операндами, а затем присваивает результат обратно левому операнду:
let num = 10;
num /= 2 // 5
В противном случае применяются правила, которые мы обсуждали для оператора деления выше:
let num = 3;
num /= '-0.5' // -6
num = 3;
num /= 0 // Infinity
num = 3;
num /= 'Jim' // NaN
Присваивание модуля: %=
Оператор присваивания по модулю выполняет операцию по модулю над двумя операндами и присваивает результат левому операнду:
let num = 10;
num %= 3 // 1
В противном случае применяются правила, которые мы обсуждали для оператора modulus:
let num = 3;
num %= '3' // 0
num = 3;
num %= 0 // NaN
num = 3;
num %= 'Jim' // NaN
Присваивание возведения в степень: **=
Оператор присваивания возведения в степень выполняет возведение в степень, где левый операнд является базовым, а правый операнд - показателем степени, и присваивает результат левому операнду:
let num = 2;
num **= 3 // 8
Здесь num
возведено в степень 3, и результат (8) присваивается обратно num
.
Как и раньше, когда второй операнд не является числом, JavaScript попытается преобразовать его с разной степенью успеха:
let num = 2;
num **= '3' // 8
num = 2;
num **= 'Jim' // NaN
Операторы побитового присваивания
Хотя до сих пор мы фокусировались на арифметических операторах, JavaScript также поддерживает набор операторов присваивания, которые работают на битовом уровне. Это операторы побитового присваивания. Если вы знакомы с двоичными числами и битовыми манипуляциями, эти операторы будут как раз по вашей части.
Эти операторы включают:
- Побитовое преобразование И присваивание (
&=
) - Побитовое присваивание (
|=
) - Побитовое назначение XOR (
^=
) - Назначение сдвига влево (
<<=
) - Назначение сдвига вправо (
>>=
) - Назначение сдвига вправо без знака (
>>>=
)
Каждый из этих операторов присваивания JavaScript выполняет определенную побитовую операцию над двоичными представлениями задействованных чисел и присваивает результат обратно левому операнду.
Более подробно мы рассмотрим побитовые операторы в разделе "Побитовые операторы" ниже.
Операторы сравнения
Оставляя область арифметики, давайте углубимся в другую важную группу операторов JavaScript — операторы сравнения. Как следует из названия, операторы сравнения используются для сравнения значений и возврата логического результата. Операторы сравнения лежат в основе многих программных решений и структур управления — от простых проверок условий до сложных логических операций.
Равенство: ==
Оператор равенства используется для проверки того, равны ли два значения друг другу. Он возвращает логический результат. Однако важно отметить, что этот оператор сравнения выполняет неполную проверку на равенство, что означает, что если операнды имеют разные типы, JavaScript попытается преобразовать их в общий тип перед выполнением сравнения:
1 == 1 // true, both operands are numbers
1 == '1' // true, string is converted to a number
Работа с объектами и массивами становится немного сложнее. ==
Оператор проверяет, ссылаются ли они на одно и то же местоположение в памяти, а не на то, идентично ли их содержимое:
const array1 = [1, 2, 3];
const array2 = [1, 2, 3];
array1 == array2 // false, even though they look the same
const array3 = array1;
array1 == array3; // true, they refer to the same memory location
В этом случае JavaScript не пытается преобразовать и сравнить значения внутри объектов или массивов. Вместо этого он проверяет, являются ли они одним и тем же объектом (то есть, занимают ли они одно и то же пространство памяти).
Неравенство: !=
Оператор неравенства используется для проверки того, не равны ли два значения друг другу. Как и ==
оператор, он выполняет проверку на отсутствие неравенства. Это означает, что, если они разных типов, он попытается преобразовать операнды в общий тип перед выполнением сравнения:
1 != 2 // true, 1 is not equal to 2
1 != '1' // false, string is converted to a number, 1 is equal to 1
'apple' != 'orange' // true, strings are different
Аналогично ==
оператору, при сравнении объектов и массивов !=
оператор проверяет, ссылаются ли они на одну и ту же ячейку памяти, а не на идентичность их содержимого.
Строгое равенство (===
) и строгое неравенство (!==
)
Операторы сравнения строгого равенства и строгого неравенства похожи на их нестрогие аналоги (==
и !=
), но они не выполняют приведение к типу. Если операнды имеют разные типы, они считаются разными, независимо от их значений.
Вот как они работают:
1 === '1' // false, because Number is not strictly equal to String
1 !== '1' // true, because Number is strictly not equal to String
null === undefined // false, even though null == undefined is true
true === 1 // false, because Boolean is not strictly equal to Number
Для объектов и массивов оператор строгого равенства ведет себя так же, как оператор свободного равенства: он проверяет, ссылаются ли они на один и тот же объект, а не на то, идентично ли их содержимое.
NaN
это особый случай. Это единственное значение в JavaScript, которое не является строго равным самому себе:
NaN === NaN // false
Больше, чем: >
Оператор больше чем проверяет, больше ли левый операнд правого операнда, возвращая логический результат. Это сравнение выполняется просто с числовыми значениями:
4 > 3 // true
2 > 2 // false
При сравнении нечисловых значений JavaScript применяет процесс преобразования, чтобы сделать их сопоставимыми. Если оба значения являются строками, они сравниваются на основе их соответствующих позиций в наборе символов Unicode:
'3' > '2' // true
'abc' > 'def' // false
Если один или оба операнда не являются строками, JavaScript пытается преобразовать их в числовые значения для сравнения:
'10' > 2 // true, '10' is converted to a number before comparison
Во время этого преобразования для определенных значений применяются определенные специальные правила. Например, null
преобразуется в 0
, undefined
преобразуется в NaN
, а логические значения true
и false
преобразуются в 1
и 0
соответственно. Однако, если какое-либо значение находится NaN
после преобразования, оператор всегда будет возвращать false
:
10 > 'Jim' // false, converting 'Jim' to a number yields NaN
Менее: <
Оператор меньше, чем возвращает true
, если левый операнд меньше правого, и false
в противном случае. Применяются те же правила, что и для оператора больше, чем; меняется только порядок операндов:
5 < 10 // true, 5 is less than 10
'10' < '2' // true, because the comparison is lexicographical
'10' < 2 // false, String '10' is coerced to a Number
Как и >
operator, <
operator использует принуждение для преобразования операндов в общий тип перед выполнением сравнения.
Больше или равно (>=
) и меньше или равно (<=
)
Операторы больше или равно (>=
) и меньше или равно (<=
) функционируют аналогично своим <
и >
аналогам, с добавленным условием равенства.
Для >=
оператора он возвращает, true
если левый операнд больше или равен правому операнду, и false
в противном случае. И наоборот, <=
оператор возвращает true
, если левый операнд меньше или равен правому операнду, и false
в противном случае. Правила принуждения и преобразования типов, описанные в разделах <
и >
непосредственно выше, применимы и здесь:
5 >= 5 // true, 5 is equal to 5
5 >= 6 // false, 5 is not greater than 6
'10' >= '2' // false, Unicode for '1' is 49, while Unicode for '2' is 50
'10' <= 20 // true, String '10' is coerced to a Number
5 >= false // true, false is coerced to 0
5 <= true // false, true is coerced to 1
null >= -1 // true, null is coerced to 0
undefined <= 0 // false, undefined is coerced to NaN
Логические операторы
Логические операторы в JavaScript предлагают способ одновременной работы с несколькими условиями. Они являются неотъемлемой частью конструкций для принятия решений в программировании, таких как if
инструкции и for
циклы.
Освоение логических операторов является ключом к управлению потоком нашего кода.
Логическое И: &&
При использовании с логическими значениями логический оператор AND возвращает true, если все условия выполнены true
и false
в противном случае.
Однако с не булевыми значениями это становится еще интереснее:
- Оператор оценивает условия слева направо.
- Если он обнаруживает значение, которое может быть преобразовано в
false
(известное как ложное значение), он останавливается и возвращает это значение. - Если все значения верны, он возвращает последнее верное значение.
Например:
true && true // true
true && false // false
'apple' && 'banana' // 'banana'
'' && 'banana' // ''
&&
Способность оператора возвращать значение операндов делает его универсальным инструментом для условного выполнения и установки значений по умолчанию. Например, мы можем использовать &&
оператор для выполнения функции или блока кода, только если выполнено определенное условие:
const userIsLoggedIn = true;
userIsLoggedIn && renderWelcomeMessage();
В этом случае, renderWelcomeMessage
будет выполняться только, если userIsLoggedIn
является true
. Если userIsLoggedIn
это false
, операция остановится на userIsLoggedIn
и renderWelcomeMessage
вызываться не будет. Этот шаблон часто используется с компонентами React для условной визуализации.
Логическое ИЛИ: ||
При использовании с логическими значениями логический оператор OR возвращает, true
если выполняется хотя бы одно условие true
и false
в противном случае.
Он также может возвращать не булевы значения, выполняя то, что известно как вычисление короткого замыкания. Он оценивает условия слева направо, останавливая и возвращая значение первого встреченного истинностного условия. Если все условия ложны, он возвращает последнее ложное значение:
true || false // true
false || true // true
'Hello' || 'World' // 'Hello'
'' || 'World' // 'World'
0 || '' // ''
Логически НЕ: !
Логический оператор NOT используется для обратного преобразования логического значения условия или выражения. В отличие от операторов &&
and ||
, !
оператор всегда возвращает логическое значение.
Если условие соответствует действительности (то есть его можно преобразовать в true
), оператор возвращает false
. Если условие неверно (то есть его можно преобразовать в false
), оператор возвращает true
:
!true // false
!false // true
!'Hello' // false
!'' // true
!0 // true
Мы можем использовать !
оператор дважды, чтобы преобразовать значение в его логический эквивалент:
!!'Hello' // true
!!'' // false
!!0 // false
Нулевой объединяющий оператор: ??
Оператор объединения с нулевым значением проверяет, является ли значение слева от него null
или undefined
, и если да, то возвращает значение справа. В противном случае он возвращает значение слева.
Хотя в некоторых отношениях он похож на ||
operator, ??
operator отличается обработкой ложных значений.
В то время как ||
оператор возвращает правый операнд, если левый операнд имеет любое ложное значение (например, null
, undefined
, false
0
, NaN
''
, ??
null
), undefined
оператор делает это только тогда, когда левый операнд имеет значение, равное, , или,,:
null ?? 'default string' // 'default string'
undefined ?? 'default string' // 'default string'
'' ?? 'default string' // ''
0 ?? 100 // 0
Установка значений по умолчанию с помощью логических операторов
Логические операторы ||
и ??
полезны для установки значений по умолчанию в программах. Вот пример выполнения этого с помощью ||
оператора:
const userColorPreference = null;
const defaultColor = 'blue';
const color = userColorPreference || defaultColor; // 'blue'
Вот пример с ??
оператором:
const userColorPreference = null;
const defaultColor = 'blue';
const color = userColorPreference ?? defaultColor; // 'blue'
Основное различие между этими логическими операторами (как указано выше) заключается в том, как они обрабатывают ложные значения:
const userColorPreference = '';
const defaultColor = 'blue';
const color1 = userColorPreference || defaultColor; // 'blue'
const color2 = userColorPreference ?? defaultColor; // ''
Побитовые операторы
Побитовые операторы в JavaScript предлагают способ выполнения операций на двоичном уровне, напрямую манипулируя битами в двоичном представлении числа. Хотя эти операторы могут быть полезны в конкретных задачах, таких как кодирование, декодирование и обработка данных, они не часто используются в повседневном программировании на JavaScript.
В этой статье мы предоставим обзор этих операторов, чтобы вы могли их распознать и понять, но мы не будем углубляться в их использование, учитывая их относительно узкоспециализированное применение.
Побитовый И: &
Побитовый оператор AND выполняет побитовую операцию AND над двоичными представлениями целых чисел. Он возвращает новое число, биты которого равны 1, если биты в одной и той же позиции в обоих операндах равны 1. В противном случае он устанавливает их равными 0:
// 5 in binary: 101
// 3 in binary: 011
5 & 3 // 1 (which is 001 in binary)
Побитовый ИЛИ: |
Побитовый оператор OR работает аналогично &
оператору, но он устанавливает бит равным 1, если хотя бы один из битов в той же позиции в операндах равен 1:
// 5 in binary: 101
// 3 in binary: 011
5 | 3 // 7 (which is 111 in binary)
Побитовый XOR: ^
Побитовый оператор XOR немного отличается. Он устанавливает бит равным 1, только если биты в одной и той же позиции в операндах разные (один равен 1, а другой равен 0):
// 5 in binary: 101
// 3 in binary: 011
5 ^ 3 // 6 (which is 110 in binary)
Побитовый НЕ: ~
Побитовый оператор NOT (~
) инвертирует биты своего операнда. Он переключает единицы на 0, а 0- на 1 в двоичном представлении числа:
// 5 in binary: 101
~5 // -6 (which is the two's complement of 101, i.e., 010)
Операторы побитового сдвига: <<, >>, >>>
Операторы побитового сдвига используются для сдвига битов двоичного числа влево или вправо. В JavaScript существует три типа: сдвиг влево (<<
), сдвиг вправо (>>
) и сдвиг вправо с заполнением нулем (>>>
).
Побитовый оператор сдвига влево (<<
) перемещает биты влево и заполняет нулями справа. Оператор сдвига вправо (>>
) сдвигает биты вправо, отбрасывая смещенные биты. Оператор сдвига вправо с заполнением нулем (>>>
) также сдвигает биты вправо, но заполняет нулями слева.
Эти операторы менее распространены в повседневном кодировании на JavaScript, но они находят применение в более специализированных областях, таких как низкоуровневое программирование, обработка двоичных данных и некоторые типы математических вычислений.
Другие операторы
Помимо обычно используемых арифметических, сравнительных, логических и побитовых операторов, JavaScript предлагает множество уникальных операторов для конкретных целей. К ним относятся операторы для обработки условной логики, управления свойствами объекта, контроля порядка операций и многого другого.
Условный (троичный) оператор: ? :
Условный троичный оператор (? :
) - это краткий способ принятия решений в нашем коде JavaScript. Он получил свое название от того, что является единственным оператором, который принимает три операнда. Синтаксис этого условного оператора следующий:
condition ? expressionIfTrue : expressionIfFalse.
Оператор работает, сначала оценивая условие. Если условие равно true
, оно выполняет expressionIfTrue
, а если оно равно false
, оно выполняет expressionIfFalse
:
const age = 15;
const status = age >= 18 ? 'Adult' : 'Minor'; // 'Minor'
В приведенном выше коде троичный оператор проверяет, age
больше или равно 18. Поскольку возраст равен 15 годам, условие оценивается как false
и 'Minor'
присваивается status
переменной.
Этот оператор может быть удобным способом написания кратких инструкций if–else, но он также может затруднить чтение кода при чрезмерном использовании или в сложных условиях.
Оператор распространения: ...
Оператор spread (...
) позволяет расширять элементы итеративного объекта (такие как массив или строка) в местах, где ожидается ноль или более аргументов или элементов. Его можно использовать в вызовах функций, литералах массива и литералах объекта:
// In function calls
const numbers = [1, 2, 3];
console.log(...numbers); // 1 2 3
// In array literals
const moreNumbers = [4, 5, ...numbers];
console.log(moreNumbers); // [4, 5, 1, 2, 3]
// In object literals
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 }
Оператор spread может быть удобным инструментом для создания копий массивов или объектов, объединения массивов или передачи элементов массива в качестве аргументов функции.
Вы можете прочитать больше об операторе распространения в кратком совете: Как использовать оператор распространения в JavaScript.
Оператор запятой: ,
Оператор запятой (,
) позволяет последовательно вычислять несколько выражений и возвращает результат последнего выражения. Выражения вычисляются слева направо.
Это особенно полезно, когда нам нужно включить несколько выражений в местоположение, которое допускает только одно, например, в разделах инициализации или обновления цикла for:
for(let i = 0, j = 10; i <= 10; i++, j--) {
console.log(`i: ${i}, j: ${j}`);
}
В приведенном выше коде оператор запятой используется для объявления и обновления двух переменных (i
и j
) в цикле for.
Необязательный оператор цепочки: ?.
Необязательная цепочка является относительно недавним дополнением к JavaScript (начиная с ES2020), которое упрощает процесс доступа к глубоко вложенным свойствам объектов. Это помогает нам писать более чистый и безопасный код, предоставляя способ попытаться получить значение свойства без необходимости явно проверять, существует ли каждая ссылка в ее цепочке:
const user = {
name: 'Jim',
address: {
street: '123 Hochstraße',
city: 'Munich'
}
};
user?.address?.city // 'Munich'
user?.contacts?.email // undefined
В приведенном выше примере user?.address?.city
обращается к city
свойству user.address
if user
и user.address
оба они существуют. В противном случае он возвращает undefined
. Такой подход позволяет избежать распространенной ошибки в JavaScript, когда попытка получить доступ к свойству undefined
or null
приводит к TypeError
:
user.contacts.email // Uncaught TypeError: Cannot read properties of undefined (reading 'email')
До создания необязательной цепочки разработчикам JavaScript приходилось использовать длинную условную логику, чтобы избежать подобных ошибок:
let email;
if (user && user.contacts) {
email = user.contacts.email;
} else {
email = 'Not specified';
}
email // 'Not specified'
Оператор конвейера: |>
Оператор конвейера (|>
) предназначен для улучшения читаемости кода, который в противном случае был бы написан с помощью вызовов вложенных функций. По сути, он позволяет нам взять результат одного выражения и вставить его в следующее. Это особенно полезно, когда мы применяем серию преобразований к значению:
const result = exclaim(capitalize(doubleSay('hello')));
console.log(result); //=> 'HELLO, HELLO!'
С помощью оператора pipeline мы можем переписать этот код следующим образом:
const result = 'hello'
|> doubleSay
|> capitalize
|> exclaim;
console.log(result); //=> 'HELLO, HELLO!'
Имейте в виду, что на момент написания оператор конвейера находится на стадии 2 процесса разработки предложения ECMAScript, что означает, что это черновик, который подвергается дальнейшим итерациям и доработкам.
Оператор группировки: ()
Оператор группировки (()
) в JavaScript используется для изменения приоритета вычисления в выражениях. Этот оператор не выполняет никаких операций над своим значением, но он управляет порядком, в котором выполняются вычисления внутри выражения.
Например, умножение и деление имеют более высокий приоритет, чем сложение и вычитание. Это означает, что в таком выражении, как 2 + 3 * 4
, сначала выполняется умножение, в результате чего получается 2 + 12
, а затем выполняется сложение, в результате чего получается 14
.
Если мы хотим изменить порядок операций, мы можем использовать оператор группировки. Например, если мы хотим, чтобы сложение выполнялось перед умножением в предыдущем примере, мы могли бы написать (2 + 3) * 4
. В этом случае сначала выполняется сложение, в результате чего получается 5 * 4
, а затем выполняется умножение, в результате чего получается 20.
Оператор группировки позволяет нам гарантировать, что операции выполняются в том порядке, в котором мы намереваемся, что может иметь решающее значение в более сложных математических или логических выражениях.
Заключение
Мы посвятили эту статью изучению широкого и порой сложного мира операторов JavaScript. Эти операторы позволяют нам манипулировать данными, управлять потоком программ и выполнять сложные вычисления.
Понимание этих операторов - это не просто академическое упражнение; это практический навык, который может улучшить нашу способность писать и понимать JavaScript.
Помните запутанный фрагмент кода, с которого мы начали? Давайте вернемся к нему и посмотрим, имеет ли он больше смысла сейчас:
const x = 10, y = 20, z = 30;
console.log((x > y ? x : y) > z ? (x > y ? x : y) : z);
Простым английским языком этот код находит максимум из трех чисел, x
, y
и z
.
Это делается с помощью комбинации троичного оператора JavaScript (? :
) и операторов сравнения (>
).
Вот как это работает:
- Выражение
(x > y ? x : y)
проверяет,x
большеy
или нет. - Если
x
большеy
, то возвращаетсяx
; в противном случае возвращаетсяy
. Другими словами, он получает максимум изx
иy
. - Затем этот результат (максимальный из
x
иy
) сравнивается сz
с>
оператором. - Если максимальное значение из
x
иy
больше, чемz
, то вычисляется вторая тройка(x > y ? x : y)
. - В этой тройке еще раз сравниваются
x
иy
, и возвращается большее из двух значений. - В противном случае, если
z
больше максимального значенияx
иy
, тоz
это максимальное из трех чисел, и оно возвращается.
Если вы сочли это объяснение запутанным, то это потому, что так оно и есть. Вложение троичных операторов, подобных этому, не очень удобно для чтения, и вычисления могли бы быть лучше выражены с помощью Math.max
:
Math.max(x, y, z)
// 30
Тем не менее, понимание того, как работают операторы JavaScript, похоже на изучение грамматики нового языка. Поначалу это может быть непросто, но как только мы усвоим основы, мы с легкостью будем составлять сложные предложения (или, в нашем случае, код).
Это веселое и простое в использовании руководство, которое в кратчайшие сроки превратит вас из новичка в уверенного программиста.
Счастливого кодирования!