Бинарные операторы в Java

Оператор принимает на вход аргументы и возвращает некоторые значения. Выделяют унарные, бинарные и тернарные операторы. Например, !false — унарный, a + b — бинарный, а? : — является единственным оператором, принимающим на вход три аргумента.
Первое, что необходимо помнить, это приоритет выполнения операторов:
- Пост-унарные операторы: exception++ и exception—
- Пре-унарные операторы: ++exception и —exception
- Остальные унарные операторы: +, -, !
- Умножение, деление, взятие остатка: *, /, %
- Сложение и вычитание: +, —
- Операторы битового сдвига: <<, >>, >>>
- Операторы сравнения: <, >, <=, >=, instanceof
- Операторы равенства-неравенства: ==, !=
- Логические операторы: &, |, ^
- Short-circuit логические операторы: &&, ||
- Тернарный оператор: boolean expression? expression1: expres-
sion2 - Операторы присваивания: =, +=, -=, *=, /=, %=, &=, ^=, !=, <<=, >>=, >>>=
Работа с бинарными арифметическими операторами
Начнем с бинарных операторов, они наиболее часто встречаются в Java. На экзамене могут предлагать достаточно сложные выражения для вычисления которых необходимо помнить порядок их выполнения.
Арифметические операторы
К арифметическим операторам относятся операторы сложения, вычитания, умножения и взятия остатка. Как я уже сказал, при вычислении необходимо помнить приоритет операторов:
int x = 2 * 5 + 3 * 4 — 8 = 10 + 12 — 8 = 14;
Также надо помнить, что приоритет выполнения может изменяться скобками (вначале вычисляется выражение в скобках):
int x = 2 * ((5 + 3) * 4 – 8) = 2 * (8 * 4 – 8) = 2 * (32 – 8) = 2 * 24 = 48;
Новички могут путать операторы целочисленного деления (/) и взятия модуля (%):
Преобразование чисел
Если аргументы бинарного оператора числовые и разные, Java применяет преобразования типов по следующим правилам:
- Если два аргумента относятся к разным типам данных, то Java преобразует аргумент менее вместительного типа к аргументу более вместительного типа
- Если один аргумент относится к целочисленному типу, а другой к вещественному, то Java преобразует значение целочисленного типа к вещественному типу
- Независимо от типов аргументов, Java вначале преобразует менее вместительные целочисленные типы (byte, short, char) к типу int
- После приведения аргументов к одному типу, Java вернет результат того же типа, которым обладают аргументы после приведения
Какого типа будет результат выполнения умножения x * y?
Согласно первому правилу, x будет преобразован к типу long, а затем будет возвращен результат того же типа.
Какого типа будет результат выполнения сложения x + y?
Здесь в лучших традициях сертификации нас подстерегает ловушка: 2.1 — это double, а 2.1f — это float. Попытка записать значение типа double в переменную типа float без явного преобразования приводит к ошибке компиляции в Java.
Какого типа будет результат выполнения сложения x + y?
По аналогии с примером 1, float будет преобразован к double, а затем будет возвращен результат типа double.
Какого типа будет результат выполнения деления x / y?
Согласно правилу 3 оба аргумента перед выполнением деления будут приведены к int, а потом по правилу 4 будет возвращен int. Ответ вовсе не short!
Какого типа будет результат выполнения операции x * y / z?
Согласно всем правилам выше вначале x будет преобразован к int’у. Затем выполняется операция умножения x (int) и y (float): x будет преобразован ко float, и результат будет принадлежать типу float. Потом выполняется float / double, поэтому float будет преобразован к double, и будет возвращен double.
Интересно развиваться в данном направлении? Посмотрите программу курса «Подготовка к сертификации Oracle Java Programmer (OCAJP)»!
Выражения и операторы
Эта глава описывает выражения и операторы языка JavaScript, такие как операторы присваивания, сравнения, арифметические, битовые, логические, строчные, и различные специальные операторы.
Полный и детальный список операторов и выражений также доступен в этом руководстве.
Операторы
В JavaScript есть следующие типы операторов. Данный подраздел описывает каждый тип и содержит информацию об их приоритетах друг над другом.
JavaScript поддерживает бинарные и унарные операторы, а также ещё один специальный тернарный оператор — условный оператор. Бинарная операция использует два операнда, один перед оператором и другой за ним:
Например: 3+4 или x*y .
В свою очередь унарная операция использует один операнд, перед или после оператора:
Например: x++ или ++x .
Операторы присваивания
В результате операции присваивания операнду слева от оператора присваивания (en-US) (знак » table-container»>
| Имя | Сокращённый оператор | Смысл |
|---|---|---|
| Присваивание (en-US) | x = y | x = y |
| Присваивание со сложением (en-US) | x += y | x = x + y |
| Присваивание с вычитанием (en-US) | x -= y | x = x — y |
| Присваивание с умножением (en-US) | x *= y | x = x * y |
| Присваивание с делением (en-US) | x /= y | x = x / y |
| Присваивание по модулю (en-US) | x %= y | x = x % y |
| Присваивание с левым сдвигом (en-US) | x <<= y | x = x << y |
| Присваивание с правым сдвигом (en-US) | x >>= y | x = x >> y |
| Присваивание с беззнаковым сдвигом вправо (en-US) | x >>>= y | x = x >>> y |
| Присваивание с побитовым AND (en-US) | x &= y | x = x & y |
| Присваивание с побитовым XOR (en-US) | x ^= y | x = x ^ y |
| Присваивание с побитовым OR (en-US) | x |= y | x = x | y |
Деструктуризация
Для более сложного присваивания в JavaScript есть синтаксис деструктуризации — это выражение, которое позволяет извлекать данные из массивов или объектов, используя синтаксис, который зеркалирует конструкторы массивов и литералы объектов.
Операторы сравнения
Оператор сравнения (en-US) сравнивает свои операнды и возвращает логическое значение, базируясь на истинности сравнения. Операнды могут быть числами, строками, логическими величинами или объектами. Строки сравниваются на основании стандартного лексикографического порядка, используя Unicode-значения. В большинстве случаев, если операнды имеют разный тип, то JavaScript пробует преобразовать их в тип, подходящий для сравнения. Такое поведение обычно происходит при сравнении числовых операндов. Единственным исключением из данного правила является сравнение с использованием операторов === и !== , которые производят строгое сравнение на равенство или неравенство. Эти операторы не пытаются преобразовать операнды перед их сравнением. Следующая таблица описывает операторы сравнения в контексте следующего примера кода:
| Оператор | Описание | Примеры, возвращающие true |
|---|---|---|
| Равно ( == ) | Возвращает true, если операнды равны. | 3 == var1 «3» == var1 3 == ‘3’ |
| Не равно ( != ) | Возвращает true, если операнды не равны. | var1 != 4 var2 != «3» |
| Строго равно ( === ) | Возвращает true, если операнды равны и имеют одинаковый тип. Смотрите также Object.is и sameness in JS. | 3 === var1 |
| Строго не равно( !== ) | Возвращает true, если операнды не равны и/или имеют разный тип. | var1 !== «3» 3 !== ‘3’ |
| Больше ( > ) | Возвращает true, если операнд слева больше операнда справа. | var2 > var1 «12» > 2 |
| Больше или равно ( >= ) | Возвращает true, если операнд слева больше или равен операнду справа. | var2 >= var1 var1 >= 3 |
| Меньше ( < ) | Возвращает true, если операнд слева меньше операнда справа. | var1 < var2 «2» < 12 |
| Меньше или равно ( <= ) | Возвращает true, если операнд слева меньше или равен операнду справа. | var1 <= var2 var2 <= 5 |
Примечание: (=>) не оператор, а нотация Стрелочных функций.
Арифметические операторы
Арифметические операторы (en-US) используют в качестве своих операндов числа (также литералы или переменные) и в качестве результата возвращают одно числовое значение. Стандартными арифметическими операторами являются сложение (+), вычитание (-), умножение (*), и деление (/). При работе с числами с плавающей точкой эти операторы работают аналогично их работе в большинстве других языках программирования (обратите внимание, что деление на ноль возвращает бесконечность Infinity ). Например:
Кроме того, JavaScript позволяет использовать следующие арифметические операторы, представленные в таблице:
| Оператор | Описание | Пример |
|---|---|---|
| Остаток от деления (en-US) ( % ) | Бинарный оператор. Возвращает целочисленный остаток от деления двух операндов. | 12 % 5 вернёт 2. |
| Инкремент (en-US) ( ++ ) | Унарный оператор. Добавляет единицу к своему операнду. Если используется в качестве префикса ( ++x ), то возвращает значение операнда с добавленной к нему единицей; а в случае применения в качестве окончания ( x++ ) возвращает значение операнда перед добавлением к нему единицы. | Если x равно 3, тогда ++x установит значение x равным 4 и вернёт 4, напротив x++ вернёт 3 и потом установит значение x равным 4. |
| Декремент (en-US) ( — ) | Унарный оператор. Вычитает единицу из значения своего операнда. Логика данного оператора аналогична оператору инкремента. | Если x равно 3, тогда —x установит значение x равным 2 и вернёт 2, напротив x— вернёт 3 и потом установит значение x равным 2. |
| Унарный минус (en-US) — | Унарный оператор. Возвращает отрицательное значение своего операнда. | Если x равно 3, тогда -x вернёт -3. |
| Унарный плюс (en-US) ( + ) | Унарный оператор. Пытается конвертировать операнд в число, если он ещё не оно. | +»3″ вернёт 3 . +true вернёт 1. |
| Возведение в степень (en-US) ( ** ) Экспериментальная возможность | Возводит основание в показатель степени , как, основаниестепень | 2 ** 3 вернёт 8 . 10 ** -1 вернёт 0.1 . |
Битовые (поразрядные) операторы
Битовые операторы (en-US) обрабатывают свои операнды как последовательности из 32 бит (нулей и единиц), а не как десятичные, шестнадцатеричные или восьмеричные числа. Например, десятичное число 9 имеет двоичное представление 1001. Битовые операторы выполняют операции над таким двоичным представлением, но результат возвращают как обычное числовое значение JavaScript.
Следующая таблица обобщает битовые операторы JavaScript.
Битовые логические операторы
Основной смысл работы битовых логических операторов состоит в следующем:
-
Операнды преобразуются в 32-битные целые числа и представляются в виде последовательности бит (нулей и единиц). Числа, имеющие более 32 битов будут сокращены. Например, следующее число имеет больше 32 битов и сконвертируется в 32-х битное:
Например, двоичным представлением числа 9 является 1001, а двоичным представлением пятнадцати — 1111. Результаты применения к этим числам битовых логических операторов выглядят следующим образом:
Обратите внимание, что все 32 бита преобразуются с использованием битового оператора НЕ, и что величины с наиболее значимым (самым левым) битом равным 1 представляют собой отрицательные числа (в представлении дополнения до двух).
Битовые операторы сдвига
Битовые операторы сдвига используют два операнда: первый представляет величину, подлежащую сдвигу, а второй операнд указывает число битовых позиций на которое должен быть сдвинут первый операнд. Направление операции сдвига определяется используемым оператором.
Операторы сдвига преобразуют свои операнды в 32-битные целые числа и возвращают результат того же типа, каким является левый операнд.
Операторы сдвига перечислены в следующей таблице.
| Оператор | Описание | Пример |
|---|---|---|
| [Сдвиг влево](</ru/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#<<_(Left_shift)>) ( << ) | Данный оператор сдвигает первый операнд на указанное количество бит влево. Излишние биты, сдвинутые влево, отбрасываются. Справа число дополняется нулевыми битами. | 9<<2 равно 36, так как 1001 после сдвига на 2 бита влево превращается в 100100, что соответствует числу 36. |
| [Сдвиг вправо с переносом знака](</ru/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#>>_(Sign-propagating_right_shift)>) ( >> ) | Данный оператор сдвигает первый операнд на указанное количество бит вправо. Излишние биты, сдвинутые вправо, отбрасываются. Слева число дополняется копиями крайнего слева бита. | 9>>2 равно 2, так как 1001 после сдвига на 2 бита вправо превращается в 10, что соответствует числу 2. Подобным же образом -9>>2 равно -3, так как знак сохраняется. |
| [Сдвиг вправо с заполнением нулями](</ru/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#>>>_(Zero-fill_right_shift)>) ( >>> ) | Данный оператор сдвигает первый операнд на указанное количество бит вправо. Излишние биты, сдвинутые вправо, отбрасываются. Слева число дополняется нулевыми битами. | 19>>>2 равно 4, так как 10011 после сдвига на 2 бита вправо превращается в 100, что соответствует числу 4. Для неотрицательных чисел сдвиг вправо с заполнением нулями и сдвиг вправо с переносом знака дают одинаковый результат. |
Логические операторы
Логические операторы (en-US) обычно используются с булевыми (логическими) значениями; при этом возвращаемое ими значение также является булевым. Однако операторы && и || фактически возвращают значение одного из операндов, поэтому, если эти операторы используются с небулевыми величинами, то возвращаемая ими величина также может быть не булевой. Логические операторы описаны в следующей таблице.
| Оператор | Использование | Описание |
|---|---|---|
| Логическое И (en-US) «( && ) | expr1 && expr2 | (Логическое И) Возвращает операнд expr1 , если он может быть преобразован в false ; в противном случае возвращает операнд expr2 . Таким образом, при использовании булевых величин в качестве операндов, оператор && возвращает true , если оба операнда true ; в противном случае возвращает false . |
| Логическое ИЛИ (en-US) ( || ) | expr1 || expr2 | (Логическое ИЛИ) Возвращает операнд expr1 , если он может быть преобразован в true ; в противном случае возвращает операнд expr2 . Таким образом, при использовании булевых величин в качестве операндов, оператор || возвращает true , если один из операндов true ; если же оба false , то возвращает false . |
| Логическое НЕ (en-US) ( ! ) | !expr | (Логическое НЕ) Возвращает false , если операнд может быть преобразован в true ; в противном случае возвращает true . |
Примерами выражений, которые могут быть преобразованы в false являются: null, 0, NaN, пустая строка («») или undefined.
Следующий код демонстрирует примеры использования оператора && (логическое И).
Следующий код демонстрирует примеры использования оператора || (логическое ИЛИ).
Следующий код демонстрирует примеры использования оператора ! (логическое НЕ).
Сокращённая оценка
Так как логические выражения вычисляются слева направо, они проверяются на возможность выполнения сокращённой оценки с использованием следующих правил:
- false && anything — сокращение с результатом false.
- true || anything — сокращение с результатом true.
Правила логики гарантируют, что данные вычисления всегда корректны. Обратите внимание, что часть «anything» представленных выше выражений не вычисляется, таким образом удаётся избежать любых побочных эффектов вычисления данной части.
Строковые операторы
В дополнение к операторам сравнения, которые могут использоваться со строковыми значениями, оператор (+) позволяет объединить две строки, возвращая при этом третью строку, которая представляет собой объединение двух строк-операндов:
Сокращённый оператор присваивания += также может быть использован для объединения (конкатенации) строк:
Условный (тернарный) оператор
Условный оператор является единственным оператором JavaScript, который использует три операнда. Оператор принимает одно из двух значений в зависимости от заданного условия. Синтаксис оператора:
Предупреждение: val1 и val2 обязательно должны что-то возвращать, поэтому в этой конструкции нельзя использовать continue или break
Если condition (условие) — истина, то оператор принимает значение val1 . В противном случае оператор принимает значение val2 . Вы можете использовать условный оператор во всех случаях, где может быть использован стандартный оператор.
Данное выражение присваивает значение «adult» переменной status , если age имеет значение 18 или более. В противном случае переменной status присваивается значение «minor».
Оператор запятая
Оператор запятая ( , ) просто вычисляет оба операнда и возвращает значение последнего операнда. Данный оператор в основном используется внутри цикла for , что позволяет при каждом прохождении цикла одновременно обновлять значения нескольких переменных.
Например, если a является двумерным массивом, каждая строка которого содержит 10 элементов, то следующий код с использованием оператора запятая позволяет выполнять одновременное приращение двух переменных. Данный код выводит на экран значения диагональных элементов массива:
Унарные операторы
Унарная операция — операция только с одним операндом.
delete
Оператор delete выполняет удаление объекта, свойства объекта, или элемента массива с заданным индексом. Синтаксис оператора:
где objectName представляет собой имя объекта, property — свойство объекта, а index — целое число, указывающее на положение (номер позиции) элемента в массиве.
Четвёртый вариант использования позволяет удалить свойство объекта, но допускается только внутри with .
Вы можете использовать оператор delete для удаления переменных, объявленных неявно, но вы не можете с его помощью удалять переменные, объявленные с помощью var .
После применения оператора delete свойство элемента меняется на undefined . Оператор delete возвращает true если выполнение операции возможно; оператор возвращает false , если выполнение операции невозможно.
Удаление элементов массива
Удаление элемента массива не влияет на длину массива. Например, если вы удалите a[3] , элемент a[4] останется a[4], a[3] станет undefined.
Когда элемент массива удаляется с помощью оператора delete , то из массива удаляется значение данного элемента. В следующем примере элемент trees[3] удалён с помощью оператора delete . Однако, элемент trees[3] остаётся адресуемым и возвращает значение undefined .
Если вы хотите, чтобы элемент оставался в массиве, но имел значение undefined, то используйте ключевое слово undefined вместо оператора delete . В следующем примере элементу trees[3] присвоено значение undefined , но элемент при этом остаётся в массиве:
Оператор typeof
Оператор typeof используется одним из следующих способов:
Оператор typeof возвращает строку обозначающую тип невычисленного операнда. Значение operand может быть строкой, переменной, дескриптором, или объектом, тип которого следует определить. Скобки вокруг операнда необязательны.
Предположим, вы определяете следующие переменные:
Оператор typeof возвращает следующие результаты для этих переменных:
Для дескрипторов true и null оператор typeof возвращает следующие результаты:
Для чисел и строк оператор typeof возвращает следующие результаты:
Для свойств оператор typeof возвращает тип значения данного свойства:
Для методов и функций оператор typeof возвращает следующие результаты:
Для встроенных объектов оператор typeof возвращает следующие результаты:
Оператор void
Оператор void используется любым из следующих способов:
Оператор void определяет выражение, которое должно быть вычислено без возвращения результата. expression — это выражение JavaScript, требующее вычисления. Скобки вокруг выражения необязательны, но их использование является правилом хорошего тона.
Вы можете использовать оператор void для указания на то, что операнд-выражение является гипертекстовой ссылкой. При этом выражение обрабатывается, но не загружается в текущий документ.
Следующий код служит примером создания гипертекстовой ссылки, которая бездействует при нажатии на неё пользователем. Когда пользователь нажимает на ссылку, void(0) вычисляется равным undefined , что не приводит ни к каким действиям в JavaScript.
Приведённый ниже код создаёт гипертекстовую ссылку, которая подтверждает отправку формы при клике на ней пользователем:
Операторы отношения
Оператор отношения сравнивает свои операнды и возвращает результат сравнения в виде булева значения.
Оператор in
Оператор in возвращает true, если указанный объект имеет указанное свойство. Синтаксис оператора:
где propNameOrNumber — строка или числовое выражение, представляющее имя свойства или индекс массива, а objectName — имя объекта.
Некоторые примеры способов использования оператора in :
Оператор instanceof
Оператор instanceof возвращает true, если заданный объект является объектом указанного типа. Его синтаксис:
где objectName — имя объекта, тип которого необходимо сравнить с objectType , а objectType — тип объекта, например, Date или Array .
Используйте оператор instanceof , когда вам необходимо подтвердить тип объекта во время выполнения программы. Например, при перехвате исключений вы можете создать различные программные переходы для обработки исключений в зависимости от типа обрабатываемого исключения.
Например, следующий код использует оператор instanceof для проверки того, является ли объект theDay объектом типа Date . Так как theDay действительно является объектом типа Date , то программа выполняет код, содержащийся в утверждении if .
Приоритет операторов
Приоритет операторов определяет порядок их выполнения при вычислении выражения. Вы можете влиять на приоритет операторов с помощью скобок.
Приведённая ниже таблица описывает приоритет операторов от наивысшего до низшего.
Более подробная версия данной таблицы, содержащая ссылки и дополнительную информацию по каждому оператору, находится в справочнике JavaScript.
Выражения
Выражением является любой корректный блок кода, который возвращает значение.
Концептуально, существуют два типа выражений: те которые присваивают переменной значение, и те, которые вычисляют значение без его присваивания.
Выражение x = 7 является примером выражения первого типа. Данное выражение использует оператор = для присваивания переменной x значения 7. Само выражение также равняется 7.
Код 3 + 4 является примером выражения второго типа. Данное выражение использует оператор «+» для сложения чисел 3 и 4 без присваивания переменной полученного результата 7.
Все выражения в JavaScript делятся на следующие категории:
- Арифметические: вычисляются в число, например: 3.14159 (Используют арифметические операторы).
- Строковые: вычисляются в текстовую строку, например: «Fred» или «234» (Используют строковые операторы).
- Логические: вычисляются в true или false (Используют логические операторы).
- Основные выражения: Базовые ключевые слова и основные выражения в JavaScript.
- Левосторонние выражения: Значениям слева назначаются значения справа.
Основные выражения
Базовые ключевые слова и основные выражения в JavaScript.
Оператор this
Используйте ключевое слово this для указания на текущий объект. В общем случае this указывает на вызываемый объект, которому принадлежит данный метод. Используйте this следующим образом:
Предположим, функция validate выполняет проверку свойства value некоторого объекта; задан объект, а также верхняя и нижняя граница величины данного свойства:
Вы можете вызвать функцию validate для обработчика события onChange для каждого элемента формы, используя this для указания на элемент формы, как это показано в следующем примере:
Оператор группировки
Оператор группировки «скобки» ( ) контролирует приоритет вычисления выражений. Например, вы можете переопределить порядок — «умножение и деление, а потом сложение и вычитание», так чтобы, например, чтобы сложение выполнялось до умножения:
Упрощённый синтаксис создания массивов и генераторов
Упрощённый синтаксис — экспериментальная возможность JavaScript, которая возможно будет добавлена в будущие версии ECMAScript. Есть 2 версии синтаксиса:
Упрощённый синтаксис для массивов.
Упрощённый синтаксис для генераторов.
Упрощённые синтаксисы существуют во многих языках программирования и позволяют вам быстро собирать новый массив, основанный на существующем. Например:
Левосторонние выражения
Значениям слева назначаются значения справа.
Вы можете использовать оператор new для создания экземпляра объекта пользовательского типа или одного из встроенных объектов. Используйте оператор new следующим образом:
super
Ключевое слово используется, чтобы вызывать функции родительского объекта. Это полезно и с классами для вызова конструктора родителя, например.
Оператор расширения
Оператор расширения позволяет выражению расширяться в местах с множеством аргументов (для вызовов функций) или множестве элементов (для массивов).
Пример: Сегодня, если у вас есть массив и вы хотите создать новый с существующей частью первого, то литерального синтаксиса массива уже не достаточно, и вы должны писать императивный (без вариантов) код, используя комбинацию push , splice , concat и т.д. Но с этим оператором код становится более коротким:
Базовые операторы, математика
Многие операторы знакомы нам ещё со школы: сложение + , умножение * , вычитание — и так далее.
В этой главе мы начнём с простых операторов, а потом сконцентрируемся на специфических для JavaScript аспектах, которые не проходят в школьном курсе арифметики.
Термины: «унарный», «бинарный», «операнд»
Прежде, чем мы двинемся дальше, давайте разберёмся с терминологией.
Операнд – то, к чему применяется оператор. Например, в умножении 5 * 2 есть два операнда: левый операнд равен 5 , а правый операнд равен 2 . Иногда их называют «аргументами» вместо «операндов».
Унарным называется оператор, который применяется к одному операнду. Например, оператор унарный минус "-" меняет знак числа на противоположный:
Бинарным называется оператор, который применяется к двум операндам. Тот же минус существует и в бинарной форме:
Формально, в последних примерах мы говорим о двух разных операторах, использующих один символ: оператор отрицания (унарный оператор, который обращает знак) и оператор вычитания (бинарный оператор, который вычитает одно число из другого).
Математика
Поддерживаются следующие математические операторы:
- Сложение + ,
- Вычитание — ,
- Умножение * ,
- Деление / ,
- Взятие остатка от деления % ,
- Возведение в степень ** .
Первые четыре оператора очевидны, а про % и ** стоит сказать несколько слов.
Взятие остатка %
Оператор взятия остатка % , несмотря на обозначение, никакого отношения к процентам не имеет.
Результат a % b – это остаток от целочисленного деления a на b .
Возведение в степень **
Оператор возведения в степень a ** b возводит a в степень b .
В школьной математике мы записываем это как a b .
Математически, оператор работает и для нецелых чисел. Например, квадратный корень является возведением в степень 1/2 :
Сложение строк при помощи бинарного +
Давайте рассмотрим специальные возможности операторов JavaScript, которые выходят за рамки школьной арифметики.
Обычно при помощи плюса ‘+’ складывают числа.
Но если бинарный оператор ‘+’ применить к строкам, то он их объединяет в одну:
Обратите внимание, если хотя бы один операнд является строкой, то второй будет также преобразован в строку.
Как видите, не важно, первый или второй операнд является строкой.
Вот пример посложнее:
Здесь операторы работают один за другим. Первый + складывает два числа и возвращает 4 , затем следующий + объединяет результат со строкой, производя действие 4 + ‘1’ = ’41’ .
Сложение и преобразование строк — это особенность бинарного плюса + . Другие арифметические операторы работают только с числами и всегда преобразуют операнды в числа.
Например, вычитание и деление:
Приведение к числу, унарный +
Плюс + существует в двух формах: бинарной, которую мы использовали выше, и унарной.
Унарный, то есть применённый к одному значению, плюс + ничего не делает с числами. Но если операнд не число, унарный плюс преобразует его в число.
На самом деле это то же самое, что и Number(. ) , только короче.
Необходимость преобразовывать строки в числа возникает очень часто. Например, обычно значения полей HTML-формы — это строки. А что, если их нужно, к примеру, сложить?
Бинарный плюс сложит их как строки:
Поэтому используем унарный плюс, чтобы преобразовать к числу:
С точки зрения математика, такое изобилие плюсов выглядит странным. Но с точки зрения программиста тут нет ничего особенного: сначала выполнятся унарные плюсы, которые приведут строки к числам, а затем бинарный ‘+’ их сложит.
Почему унарные плюсы выполнились до бинарного сложения? Как мы сейчас увидим, дело в их приоритете.
Приоритет операторов
В том случае, если в выражении есть несколько операторов – порядок их выполнения определяется приоритетом, или, другими словами, существует определённый порядок выполнения операторов.
Из школы мы знаем, что умножение в выражении 1 + 2 * 2 выполнится раньше сложения. Это как раз и есть «приоритет». Говорят, что умножение имеет более высокий приоритет, чем сложение.
Скобки важнее, чем приоритет, так что, если мы не удовлетворены порядком по умолчанию, мы можем использовать их, чтобы изменить приоритет. Например, написать (1 + 2) * 2 .
В JavaScript много операторов. Каждый оператор имеет соответствующий номер приоритета. Тот, у кого это число больше, – выполнится раньше. Если приоритет одинаковый, то порядок выполнения – слева направо.
Отрывок из таблицы приоритетов (нет необходимости всё запоминать, обратите внимание, что приоритет унарных операторов выше, чем соответствующих бинарных):
| Приоритет | Название | Обозначение |
|---|---|---|
| … | … | … |
| 15 | унарный плюс | + |
| 15 | унарный минус | — |
| 14 | возведение в степень | ** |
| 13 | умножение | * |
| 13 | деление | / |
| 12 | сложение | + |
| 12 | вычитание | — |
| … | … | … |
| 2 | присваивание | = |
| … | … | … |
Так как «унарный плюс» имеет приоритет 15 , который выше, чем 12 у «сложения» (бинарный плюс), то в выражении "+apples + +oranges" сначала выполнятся унарные плюсы, а затем сложение.
Присваивание
Давайте отметим, что в таблице приоритетов также есть оператор присваивания = . У него один из самых низких приоритетов: 2 .
Именно поэтому, когда переменной что-либо присваивают, например, x = 2 * 2 + 1 , то сначала выполнится арифметика, а уже затем произойдёт присваивание = с сохранением результата в x .
Присваивание = возвращает значение
Тот факт, что = является оператором, а не «магической» конструкцией языка, имеет интересные последствия.
Большинство операторов в JavaScript возвращают значение. Для некоторых это очевидно, например сложение + или умножение * . Но и оператор присваивания не является исключением.
Вызов x = value записывает value в x и возвращает его.
Благодаря этому присваивание можно использовать как часть более сложного выражения:
В примере выше результатом (a = b + 1) будет значение, которое присваивается переменной a (то есть 3 ). Потом оно используется для дальнейших вычислений.
Забавное применение присваивания, не так ли? Нам нужно понимать, как это работает, потому что иногда это можно увидеть в JavaScript-библиотеках.
Однако писать самим в таком стиле не рекомендуется. Такие трюки не сделают ваш код более понятным или читабельным.
Присваивание по цепочке
Рассмотрим ещё одну интересную возможность: цепочку присваиваний.
Такое присваивание работает справа налево. Сначала вычисляется самое правое выражение 2 + 2 , и затем результат присваивается переменным слева: c , b и a . В конце у всех переменных будет одно значение.
Опять-таки, чтобы код читался легче, лучше разделять подобные конструкции на несколько строчек:
Польза от такого стиля особенно ощущается при быстром просмотре кода.
Сокращённая арифметика с присваиванием
Часто нужно применить оператор к переменной и сохранить результат в ней же.
Операторы
Операторы являются специальными функциями, принимающими один или несколько операндов и возвращающими значения. Операнд — это значение, обычно литерал, переменная или выражение, которые оператор использует в качестве входных данных. Например, в следующем программном коде операторы сложения ( + ) и умножения ( * ) используются с тремя литеральными операндами (2, 3 , 4 ) для получения значения. Это значение затем используется оператором присваивания ( = ), чтобы назначить возвращаемое значение, 14, переменной sumNumber .
Операторы могут быть унарными, бинарными или тернарными. Унарный оператор принимает один операнд. Например, оператор инкрементального увеличения ( ++ ) является унарным оператором, поскольку он принимает только один операнд. Бинарный оператор принимает два операнда. Например, оператор деления ( / ) принимает два операнда. Тернарный оператор принимает три операнда. Например, оператор условия ( ?: ) принимает три операнда.
Некоторые операторы являются перегруженными ; это означает, что они ведут себя по-разному в зависимости от типа или количества переданных ими операндов. Оператор сложения ( + ) является примером перегруженного оператора, который ведет себя по-разному в зависимости от типа операндов. Если оба операнда являются числами, оператор сложения возвращает сумму этих значений. Если оба операнда являются строками, оператор сложения возвращает последовательное соединение двух операндов. В следующем программном коде показано, как оператор по-разному ведет себя в зависимости от операндов.
Поведение операторов также может отличаться в зависимости от числа передаваемых операндов. Оператор вычитания ( — ) является одновременно унарным и бинарным оператором. Если оператор вычитания используется только с одним операндом, оператор меняет его знак и возвращает результат. Если оператор вычитания используется с двумя операндами, он возвращает разность между ними. В следующем примере показан оператор вычитания, используемый вначале как унарный оператор, а затем как бинарный.
Старшинство и ассоциативность операторов
Старшинство и ассоциативность операторов определяют порядок, в котором обрабатываются операторы. Хотя может показаться абсолютно естественным для всех, кто знаком с арифметическими операциями, что компилятор должен обрабатывать оператор умножения ( * ) перед оператором сложения ( + ), в действительности компилятору необходимо явное указание того, какие операторы обрабатывать в первую очередь. Такие инструкции обычно упоминаются как старшинство операторов . ActionScript определяет старшинство операторов по умолчанию, которое можно изменить с помощью оператора скобки ( () ). Например, в следующем программном коде изменяется заданное по умолчанию старшинство операторов из предыдущего примера, чтобы заставить компилятор обработать оператор сложения перед оператором умножения.
Могут возникнуть ситуации, в которых в одном выражении встретятся два или больше операторов одного старшинства. В таких случаях компилятор использует правила ассоциативности , чтобы определить, какой оператор обрабатывать в первую очередь. Все бинарные операторы, за исключением оператора присваивания, являются ассоциируемыми слева , а это значит, что операторы слева обрабатываются раньше, чем операторы справа. Операторы присваивания и оператор условия ( ?: ) являются ассоциируемыми справа операторами, и это означает, что операторы справа обрабатываются раньше, чем операторы слева.
Например, рассмотрим операторы меньше ( < ) и больше ( > ), имеющие одинаковое старшинство. Если оба оператора используются в одном выражении, оператор слева обрабатывается раньше, поскольку оба оператора являются ассоциируемыми слева. Это означает, что результат выполнения следующих двух инструкций будет одинаков.
Оператор «больше» обрабатывается в первую очередь, что приводит к итоговому значению true , поскольку операнд 3 больше, чем операнд 2. Значение true затем передается оператору «меньше» вместе с операндом 1. В следующем программном коде показано промежуточное состояние.
Оператор «меньше» преобразует значение true в цифровое значение 1 и сравнивает это числовое значение со вторым операндом 1, возвращая значение false (значение 1 не меньше значения 1).
Заданную по умолчанию ассоциативность слева можно изменить с помощью оператора скобки. Можно заставить компилятор обрабатывать оператор «меньше» первым, если заключить этот оператор и его операнды в скобки. В следующем примере используется оператор скобки, чтобы получить другой результат, взяв в качестве операндов числа из предыдущего примера.
Оператор «меньше» обрабатывается в первую очередь, что приводит к итоговому значению false , поскольку операнд 2 не меньше, чем операнд 1. Значение false затем передается оператору «больше» вместе с операндом 3. В следующем программном коде показано промежуточное состояние.
Оператор «больше» преобразует значение false в числовое значение 0 и сравнивает это числовое значение с операндом 3, возвращая значение true (значение 3 больше, чем 0).
В следующей таблице приведен список операторов ActionScript 3.0 в порядке уменьшения их старшинства. Каждая строка таблицы содержит операторы одинакового старшинства. Каждая строка операторов имеет более высокое старшинство, чем строка, отображающаяся ниже в таблице.