- Присваивание
- Арифметические операторы
- Термины: «унарный», «бинарный», «операнд»
- Сложение строк
- Приоритет
- Инкремент/декремент:
++, -- - Побитовые операторы
- Вызов операторов с присваиванием
- Оператор запятая
Для работы с переменными, со значениями, JavaScript поддерживает все стандартные операторы, большинство которых есть и в других языках программирования.
Присваивание
Оператор присваивания выглядит как знак равенства =:
var i = 1 + 2; alert(i); // 3
Он вычисляет выражение, которое находится справа, и присваивает результат переменной. Это выражение может быть достаточно сложным, включать в себя любые другие переменные:
var a = 1; var b = 2; *!* a = b + a + 3; // (*) */!* alert(a); // 6
Выражение может включать в себя и саму переменную, в которую оно присвоится. При этом в строке (*) сначала произойдет вычисление, использующее текущее значение a (т.е. 1), после чего результат перезапишет старое значение a.
"=" возвращает значениеВсе операторы возвращают значение. Вызов x = ... записывает выражение справа в x, а затем возвращает его. Так что присваивание можно использовать как часть более сложного выражения:
var a = 1; var b = 2; *!* var c = 3 - (a = b); // c = 1 */!* alert(a = b); // 2
В примере выше результатом a = b является значение, которое записывается в a (т.е. 2).
Забавное применение присваивания, не так ли?
Знать, как это работает — стоит обязательно, а вот писать самому — только если вы уверены, что это сделает код более читаемым и понятным.
Арифметические операторы
Базовые арифметические операторы знакомы нам с детства: это плюс +, минус -, умножить *, поделить /.
Например:
alert(2 + 2); // 4
Или чуть сложнее:
var i = 2; i = (2 + i) * 3 / i; alert(i); // 6
Более редкий арифметический оператор % интересен тем, что никакого отношения к процентам не имеет. Его результат для a % b - это остаток от деления a на b. Например:
alert(5 % 2); // 1, остаток от деления 5 на 2 alert(8 % 3); // 2, остаток от деления 8 на 3 alert(6 % 3); // 0, остаток от деления 6 на 3
Термины: «унарный», «бинарный», «операнд»
У операторов есть своя терминология, которая используется во всех языках програмирования.
Операнд — то, к чему применяется оператор. Например: 5 * 2 — оператор умножения с левым и правым операндами. Другое название: «аргумент оператора».
Унарным называется оператор, который применяется к одному выражению. Например, оператор унарный минус "-" меняет знак числа на противоположный:
alert( -(1+2) ); // -3, унарный минус alert( -(-3) ); // 3
Бинарным называется оператор, который применяется к двум операндам. Тот же минус существует и в бинарной форме:
alert( 3 - 1 ); // 2, бинарный минус
Большинство операторов — бинарные, например, умножение "*" требует ровно два аргумента.
Операторы плюс "+" и минус "-" в JavaScript существуют и в бинарной и в унарной формах.
Работа унарного "+" и бинарного "+" в JavaScript существенно различается. Это действительно разные операторы. Унарный плюс приводит значение к числу, а бинарный — складывает, в том числе строки. Мы еще встретимся с этим.
Сложение строк
Если бинарный оператор + применить к строкам, то он их объединяет в одну:
var a = "моя" + "строка"; alert(a); // моястрока
Если хотя бы один аргумент является строкой, то второй будет также преобразован к строке!
Причем не важно, справа или слева находится операнд-строка,в любом случае нестроковый аргумент будет преобразован. Например:
alert( '1' + 2 ); // "12" alert( 2 + '1' ); // "21"
Это приведение к строке — особенность бинарного оператора плюс "+". Любой другой арифметический оператор, наоборот, всегда преобразует операнды к числам, например:
alert( '1' - 2 ); // -1 alert( 6 / '2'); // 3
Приоритет
В том случае, если в выражении есть несколько операторов - порядок их выполнения определяется приоритетом.
Из школы мы знаем, что умножение в выражении 2*2+5 выполнится раньше сложения, т.к. его приоритет выше, а скобки явно задают порядок выполнения. Но в JavaScript - гораздо больше операторов, поэтому существует целая таблица приоритетов. В ней каждый оператор получает числовой приоритет, и тот, у кого число меньше - выполнится раньше.
Отрывок из таблицы:
| … | … | ... |
| 5 | умножение | * |
| 5 | деление | / |
| 6 | сложение | + |
| 6 | вычитание | - |
| 16 | присвоение | = |
| … | … | ... |
Так что в выражении x = 2*2+5 сначала выполнится умножение (приоритет 5), затем сложение (приоритет 6), и после них - присвоение (приоритет 16). Если приоритет одинаковый (сложение и вычитание), то порядок выполнения - слева направо.
Эта таблица содержит много операторов, которые мы пока не знаем, но обязательно изучим.
Инкремент/декремент: ++, --
Одной из наиболее частых операций в JavaScript, как и во многих других языках программирования, является увеличение или уменьшение переменной на единицу.
Для этого существуют даже специальные операторы:
- Инкремент
++увеличивает на 1:
var i = 2; i++; // более короткая запись для i = i + 1. alert(i); // 3
- Декремент
--уменьшает на 1:
var i = 2; i--; // более короткая запись для i = i - 1. alert(i); // 1
Инкремент/декремент можно применить только к переменной.
Код 5++ даст ошибку.
Вызывать эти операторы можно не только после, но и перед переменной: i++ (называется «постфиксная форма») или ++i («префиксная форма»).
Дело в том, что операторы инкремент и декремент уникальны. В отличие от остальных операторов, они делают сразу две вещи:
- Меняют значение переменной.
- Возвращают результат.
Разница между постфиксной и префиксной формами заключается в последовательности этих шагов.
Посмотрим подробнее, на примере:
var i = 1; var a = ++i; // (*) alert(a); // *!*2*/!*
В строке (*) вызов ++i увеличит переменную (шаг 1), а затем вернёт ее значение в a (шаг 2). То есть, в a попадёт значение i после увеличения.
Постфиксная же форма делает шаги наоброт: i++ сначала возвращает значение (шаг 2), а потом меняет переменную (шаг 1).
Поэтому в примере ниже в a попадёт старое значение i, равное 1:
var i = 1; var a = i++; // (*) alert(a); // *!*1*/!*
Инкремент/декремент можно использовать в любых выражениях. При этом он имеет более высокий приоритет и выполняется раньше, чем арифметические операции:
var i = 1; alert( 2 * ++i ); // 4
var i = 1; alert( 2 * i++ ); // 2, выполнился раньше но значение вернул старое
Посмотрите, понятно ли вам, почему код ниже работает именно так?
var x = 1; i = ++x; alert(i); //2 e = x++; alert(e); //2 a = (2+ ++x); alert(a); //6 b = (2+ x++); alert(b); //6 c = (2+ ++x +2); alert(c); //10 d = (2+ x++ +2); alert(d); //10
var x = 1; // префиксная форма сначала увеличивает x до 2, а потом возврващает i = ++x; alert(i); // поэтому i = 2 // постфиксная форма возвращает значение (2), а затем увеличивает его e = x++; alert(e); // e = 2, значение x возросло до 3 // сначала увеличили x до 4, потом возвратили a = (2+ ++x); alert(a); // так что 2+4 = 6 // возвратили значение 4, затем увеличили x до 5 b = (2+ x++); alert(b); // 2 + 4 = 6 // та же логика.. c = (2+ ++x +2); alert(c); //10 d = (2+ x++ +2); alert(d); //10
Побитовые операторы
Побитовые операторы рассматривают аргументы как 32-разрядные целые числа и работают на уровне их внутреннего двоичного представления.
Эти операторы не являются чем-то специфичным для JavaScript, они поддерживаются в большинстве языков программирования.
Поддерживаются следующие побитовые операторы:
- AND(и) (
&) - OR(или) (
|) - XOR(побитовое исключающее или) (
^) - NOT(не) (
~) - LEFT SHIFT(левый сдвиг) (
<<) - RIGHT SHIFT(правый сдвиг) (
>>) - ZERO-FILL RIGHT SHIFT(правый сдвиг с заполнением нулями) (
>>>)
Вы можете более подробно почитать о них в отдельной статье Побитовые операторы.
Вызов операторов с присваиванием
Часто нужно применить оператор к переменной и сохранить результат в ней же, например:
n = n + 5; d = d * 2;
Этот синтаксис можно сократить при помощи совмещенных операторов: +=, -=, *=, /=, >>=, <<=, >>>=, &=, |=, ^=, вот так:
n = 2; n += 5; // теперь n=7 (аналогично n = n + 5) n *= 2; // теперь n=14 (аналогично n = n * 2)
Все операторы присваивания имеют очень низкий приоритет, т.к. должны выполняться после остальных вычислений.
Чему будет равен x в примере ниже?
var a = 2; var x = 1 + (a *= 2);
Ответ: x = 5.
Оператор присваивания возвращает значение, которое будет записано в переменную, например:
var a = 2; alert( a *= 2 ); // 4
Отсюда x = 1 + 4 = 5.
Оператор запятая
Запятая тоже является оператором. Ее можно вызвать явным образом, например:
*!* a = (5, 6); */!* alert(a);
Запятая позволяет перечислять выражения, разделяя их запятой ','. Каждое из них — вычисляется и отбрасывается, за исключением последнего, которое возвращается.
Запятая - единственный оператор, приоритет которого ниже присваивания. В выражении a = (5,6) для явного приоритета использованы скобки, иначе оператор '=' выполнялся бы до запятой ',', т.е. как (a=5), 6.
Зачем нужен такой оператор, который отбрасывает значения всех перечисленных выражений, кроме последнего?
Обычно он используется для того, чтобы делать несколько действий в одной строке, в составе более сложных конструкций. Например:
// три операции в одной строке
for (*!*a = 1, b = 3, c = a*b*/!*; a < 10; a++) {
...
}
Такие трюки используются во многих JavaScript-фреймворках для укорачивания кода.
Комментарии
- Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
- Если ваш комментарий касается задачи -- откройте её в отдельном окне и напишите там.
- Комментарии без смысла, с рекламой или не о статье вообще - удаляются.