Какие из этих операторов выполняет не только арифметические операции?
Cо 2 и 3 вариантом понятно. Оператор «-» выполняет приведение типов string в number, что не является арифметической операцией. Оператор «+» выполняет арифметическую операцию сложения и выполняет конкатенацию строк. А остальные?
Отслеживать
задан 1 дек 2019 в 20:27
195 1 1 золотой знак 3 3 серебряных знака 19 19 бронзовых знаков
и где интересно сказано, что — выполняет такое приведение? прям вот такими словами, и почему тогда + не делает того же?
1 дек 2019 в 20:40
@teran в тестах js
1 дек 2019 в 20:54
@ruben 42 / ‘1’ ; +»42″ ; «42» * «1» .
2 дек 2019 в 2:02
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Оператор + помимо сложения чисел еще и конкатенирует (складывает) строку. Пример со строкой:
console.log('Evgeny ' + 'Eremenko') // так ведет себя оператор + со строками
и с числом:
console.log (2 + 1) // так ведет себя оператор + с числами
Отслеживать
ответ дан 2 дек 2019 в 0:34
Roman Abramov Roman Abramov
118 8 8 бронзовых знаков
про «+» и «-» — это понятно, я спрашивал про остальные
2 дек 2019 в 19:48
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.21.1314
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
JavaScript: Инкремент и декремент
Из языка Си в JavaScript перекочевали две операции: инкремент ++ и декремент — , которые очень часто встречаются вместе с циклами. Эти унарные операции увеличивают и уменьшают на единицу число, записанное в переменную:
let i = 0; i++; // 0 i++; // 1 i--; // 2 i--; // 1
Кроме постфиксной формы, у них есть и префиксная:
let i = 0; ++i; // 1 ++i; // 2 --i; // 1 --i; // 0
Кажется, что нет никакой разницы между постфиксной и префиксной формами. Но тут начинаются сложности.
В отличие от всех остальных операций, которые не имеют побочных эффектов и просто возвращают новое значение, инкремент и декремент не только возвращают значение, но и изменяют значение переменной.
При использовании префиксной нотации сначала происходит изменение переменной, а потом возврат.
При использовании постфиксной нотации — наоборот: можно считать, что сначала происходит возврат, а потом изменение переменной.
Правило работает одинаково для инкремента и декремента. Для простоты рассмотрим только инкремент:
let x = 5; console.log(++x); // => 6 console.log(x); // => 6 console.log(x++); // => 6 console.log(x); // => 7
- Вывели на экран ++x . Это префиксный инкремент, поэтому сначала значение переменной увеличилось на 1, потом результат вернулся и вывелся на экран.
- Так как значение изменилось, console.log(x) вывел 6.
- Теперь выводим на экран x++ . Это постфиксный инкремент, поэтому возвращено значение, содержавшееся в переменной до её увеличения на 1.
- Так как значение изменилось, console.log(x) вывел 7.
Особенно страшным это становится тогда, когда инкремент вставляют внутрь других операций: x = i++ — 7 + —h . Понять такой код почти невозможно, и его написание должно рассматриваться как тяжкое преступление.
Например, в языке JavaScript линтер (программа, проверяющая код) сразу начинает ругаться, когда встречает использование инкремента или декремента.
Рекомендации по использованию:
- Никогда не мешайте в рамках одного выражения операции/функции без побочных эффектов с операциями/функциями, обладающими побочными эффектами.
- Используйте инкремент и декремент только там, где нет разницы между префиксным и постфиксным вариантом: отдельно от всего, на своей собственной строчке кода.
Задание
Напишите функцию makeItFunny() , которая принимает на вход строку и возвращает её копию, у которой каждый n-ный элемент переведен в верхний регистр. n – задается на входе в функцию.
Для определения каждого n-ного элемента понадобится остаток от деления % . Подумайте, как его можно использовать.
const text = 'I never look back'; // Каждый третий элемент makeItFunny(text, 3); // 'I NevEr LooK bAck'
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Полезное
Определения
- Побочный эффект — действие, которое изменяет внешнее окружение (среду выполнения). Например, вывод на экран или отправка письма.
Базовая математика в JavaScript — числа и операторы
В этой части курса мы обсуждаем математику в JavaScript — как мы можем использовать operators (en-US) и другие функции, чтобы успешно манипулировать числами для выполнения наших задач.
| Необходимые условия: | Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript. |
|---|---|
| Цель: | Ознакомление с основами математики в JavaScript. |
Все любят математику
Хорошо, может быть, не все. Некоторые из нас любят математику, некоторые из нас ненавидели математику с тех пор, как мы изучали таблицу умножения в школе, а некоторые из нас находятся где-то между ними. Но никто из нас не может отрицать, что математика является фундаментальной частью жизни, и мы не можем обойтись без неё. Это особенно актуально, когда мы учимся программировать на JavaScript (или на любом другом языке, если на то пошло) — большая часть того, что мы делаем, опирается на обработку числовых данных, вычисление новых значений и т.д. Так что не удивительно, что JavaScript имеет полнофункциональный набор математических функций.
В этой статье обсуждаются только основные разделы, которые вам нужно знать сейчас.
Типы чисел
В программировании даже скромная система десятичных чисел, которую мы все так хорошо знаем, сложнее, чем вы думаете. Мы используем разные термины для описания различных типов десятичных чисел. Например:
- Целые — это целые числа, такие как: 10, 400, или -5.
- С плавающей точкой(или: с плавающей запятой) — имеют целую и дробную части, например: 12.5 или 56.7786543.
- Doubles — тип чисел с плавающей точкой, которые имеют большую точность, чем стандартные числа с плавающей точкой (что означает, что они точны для большего числа десятичных знаков).
У нас даже есть разные типы числовых систем:
- Бинарная — низкоуровневый язык компьютеров; нули и единицы (0 и 1);
- Восьмеричная — 8-ми разрядная, использует 0–7 в каждом столбце;
- Десятичная — 10-ти разрядная, использует 0-9 в каждом столбце;
- Шестнадцатеричная — 16-ти разрядная, используют 0–9 и потом a–f в каждом столбце. Вы, возможно, уже встречали эти числа, когда задавали цвет в CSS.
Прежде чем взорвётся ваш мозг, остановитесь прямо здесь и сейчас!
Во-первых, мы просто будем придерживаться десятичных чисел на протяжении всего курса; вы редко когда будете сталкиваться с необходимостью думать в других числовых системах, если вообще когда-либо с ней столкнётесь.
Во-вторых, в отличие от некоторых других языков программирования, JavaScript имеет только один тип данных для чисел, как вы догадались это Number . Это означает, независимо от типа чисел, с которыми вы работаете в JavaScript, обрабатывать вы их будете точно так же.
Для меня всё — числа
Давайте быстро поиграем с некоторыми числами, чтобы снова познакомиться с основным синтаксисом, который нам нужен. Введите команды, перечисленные ниже, в вашу консоль (developer tools JavaScript console), или используйте простую встроенную консоль.
-
Прежде всего, давайте объявим пару переменных и инициализируем их целым числом и числом с плавающей точкой, соответственно, затем введите имена переменных обратно, чтобы проверить, что все в порядке:
var myInt = 5; var myFloat = 6.667; myInt; myFloat;
typeof myInt; typeof myFloat;
Арифметические операторы
Арифметические операторы — это основные операторы, которые мы используем для различных математических операций, например таких, как сложение или вычитание:
| Оператор | Имя | Функция | Пример |
|---|---|---|---|
| + | Сложение | Объединение чисел в одно целое. | 6 + 9 |
| — | Вычитание | Вычитает правое число от левого. | 20 — 15 |
| * | Умножение | Умножает два числа вместе. | 3 * 7 |
| / | Деление | Делит левое число на правое. | 10 / 5 |
| % | Модуль числа | Возвращает значение остатка при делении первого числа на второе. Результат будет иметь тот же знак, что и первое число. | 11 % 3 = 2 (поскольку число 3 вмещается три раза, остатком будет число 2) |
| ** | показатель степени | Возводит базовое число в указанную степень, то есть количество базовых чисел, указанных экспонентой, умножается вместе. Впервые он был представлен в EcmaScript 2016. | 5 ** 5 (возвращает 3125, или как: 5*5*5*5*5) |
Примечание: Иногда числа участвующие в математических операциях называют операндами ( operands (en-US) ).
Нам, вероятно, не нужно учить вас базовым математическим операциям, но мы хотели бы проверить ваше понимание синтаксиса. Попробуйте ввести приведённые ниже примеры в свою консоль (developer tools JavaScript console), или используйте встроенную консоль, с которой вы уже знакомы, чтобы ознакомиться с синтаксисом.
-
Для начала попробуйте ввести простые примеры, такие как:
10 + 7; 9 * 8; 60 % 3;
var num1 = 10; var num2 = 50; 9 * num1; num2 / num1;
5 + 10 * 3; (num2 % 9) * num1; num2 + num1 / 8 + 2;
Некоторые примеры выше могут дать вам не тот результат, которого вы ожидали; приведённый ниже раздел может дать ответ на вопрос о том, почему.
Приоритет операторов
Давайте взглянем на последний пример сверху. Предположим, что num2 содержит значение 50 и num1 содержит значение 10 (как и было обозначено выше):
+ num1 / 8 + 2;
Будучи человеком, вы, вероятно, прочитаете это как «50 плюс 10 равно 60», затем «8 плюс 2 равно 10», и, наконец, «60 делить на 10 равно 6».
Но браузер видит это по-другому: «10 делить на 8 равно 1.25», затем «50 плюс 1.25 плюс 2 равно 53.25».
Это происходит из-за приоритета операторов — некоторые операторы будут применены перед другими в процесс вычисления суммы (в программировании её называют выражением). Приоритет операторов в JavaScript ничем не отличается от приоритета арифметических операций, который вы изучали в школе — умножение и деление всегда выполняются первыми, затем сложение и вычитание (сумма всегда вычисляется слева направо).
Если вы хотите переопределить порядок выполнения операторов, вы можете окружить парными скобками часть выражения, которая должна быть выполнена первой. Для получения результата 6 вам следует сделать следующее:
(num2 + num1) / (8 + 2);
Результат этого выражения равен 6.
Примечание: полный список операторов JavaScript и приоритетов их выполнения можно найти по этой ссылке: Expressions and operators.
Операторы инкремента и декремента
Иногда вам захочется повторно добавить или вычесть единцу к/из значению числовой переменной. Это можно сделать с помощью оператора инкремента ( ++ ) и декремента ( — ). Мы использовали ++ в нашей игре «Угадай число» в статье первое погружение в JavaScript, где мы добавляли 1 к переменной guessCount , в которой хранилось значение количества попыток пользователя после каждого хода.
Примечание: инкремент и декремент часто используются в циклах, о которых вы узнаете позже. Например, если вы захотите пройтись по списку цен и добавить к каждой налог с продаж, вам придётся в цикле обойти каждую цену и провести необходимые вычисления для учёта налога. Инкремент будет использован для перехода на новую ячейку списка при необходимости. У нас есть несложный пример реализации такого списка — попробуйте и взгляните на код чтобы посмотреть, сможете ли вы найти инкременты! Мы взглянем на циклы поближе позже по ходу курса.
Давайте попробуем сыграть с этим в вашей консоли. Для начала заметим, что вы не можете использовать инкремент/декремент непосредственно к числу, что может показаться странным. Дело в том, что мы присваиваем к переменной новое обновлённое число, а не просто вычисляем значение. Следующий пример приведёт к ошибке:
Таким образом, вы можете применить инкремент только к существующим переменным:
var num1 = 4; num1++;
Так, вторая странность! Если вы сделаете это, вы получите значение 4 — браузер возвращает текущее число, после чего применяет к нему оператор инкремента. Вы можете удостовериться в том, что инкремент был применён, узнав значение переменной ещё раз:
То же самое для — : попробуйте пример ниже
var num2 = 6; num2--; num2;
Примечание: вы можете заставить делать это в другом порядке — применить инкремент/декремент и только потом вернуть значение. Для этого необходимо записать оператор слева от переменной, а не справа. Попробуйте пример сверху ещё раз, но в этот раз используйте ++num1 и —num2 .
Операторы присваивания
Операторы присваивания — операторы, которые присваивают значение переменным. Мы уже много раз использовали самый простой из них, = , он просто приравнивает значение переменной слева к значению справа:
var x = 3; // x содержит значение 3 var y = 4; // y содержит значение 4 x = y; // x теперь содержит значение y (x == 4)
Однако есть ещё несколько сложных конструкций, которые позволяют делать ваш код более простым и аккуратным. Наиболее часто используемые перечислены ниже:
| Operator | Name | Purpose | Example | Shortcut for |
|---|---|---|---|---|
| += | Присваивание сложения | Прибавляет значение справа к переменной слева и возвращает новое значение переменной | x = 3; x += 4; | x = 3; x = x + 4; |
| -= | Присваивание вычитания | Вычитает значение справа из переменной слева и возвращает новое значение переменной | x = 6; x -= 3; | x = 6; x = x — 3; |
| *= | Присваивание умножения | Умножает переменную слева на значение справа и возвращает новое значение переменной | x = 2; x *= 3; | x = 2; x = x * 3; |
| /= | Присваивание деления | Делит переменную слева на значение справа и возвращает новое значение переменной | x = 10; x /= 5; | x = 10; x = x / 5; |
Попробуйте использовать такие конструкции, что понять, как они работают. Сможете ли вы определить значение до того, как напишите вторую строку?
Заметьте, что значение справа может быть как числом (константой), так и переменной, например:
var x = 3; // x содержит значение 3 var y = 4; // y содержит значение 4 x *= y; // x содержит значение 12
Примечание: есть ещё другие операторы присваивания, в этой статье перечислены только самые базовые.
Активное обучение: меняем размеры коробки
В этом упражнении вы будете пользоваться числами и операторами для работы с размерами коробки. Коробка рисуется с помощью API браузера, которое называется Canvas API. Вам не следует беспокоиться о том, как это работает — просто сосредоточьтесь на математике. Ширина и высота коробки (в пикселях) определяются переменными x и y , которые изначально равны 50.
В коде сверху, который вы можете изменять, под комментарием есть две строчки, с помощью которых вы можете увеличивать/уменьшать размеры коробки. Мы хотим, чтобы вы выполнили несколько заданий:
- Поменяйте строчку с размером x так, чтобы коробка была шириной 50px, причём 50 должно быть вычислено с помощью чисел 43 и 7 и арифметического оператора.
- Поменяйте строчку с размером y так, чтобы коробка была высотой 75px, причём 75 должно быть вычислено с помощью чисел 25 и 3 и арифметического оператора.
- Поменяйте строчку с размером y так, чтобы коробка была высотой 250, при этом 250 вычислено с помощью двух чисел и оператором взятия остатка (модуль).
- Поменяйте строчку с размером y так, чтобы коробка была высотой 150px, причём 150 вычислено с помощью трёх чисел и операторов вычитания и деления.
- Поменяйте строчку с размером x так, чтобы коробка была шириной 200px, при этом 200 вычислено с помощью числа 4 и оператора присваивания.
- Поменяйте строчку с размером y так, чтобы коробка была высотой 200px, причём 200 вычислено с помощью чисел 50 и 3 и операторов умножения и присваивания сложения.
Не расстраивайтесь, если вы не поняли код сверху. Нажмите кнопку Reset для запуска программы снова. Если вы смогли ответить верно на все вопросы, попробуйте поэкспериментировать с кодом ещё (или, например, предложить друзьям несколько заданий).
Операторы сравнения
Иногда нам может понадобиться проверить какое-либо условие, а затем поступить в зависимости от результата — для этого мы используем операторы сравнения.
| Оператор | Имя | Назначение | Пример |
|---|---|---|---|
| === | Строгое равенство | Проверяет левое и правое значения на идентичность | 5 === 2 + 4 |
| !== | Строгое неравенство | Проверяет левое и правое значения на неидентичность | 5 !== 2 + 3 |
| Меньше | Проверяет, меньше ли левое значение правого | 10 < 6 | |
| > | Больше | Проверяет, больше ли левое значение правого | 10 > 20 |
| Меньше или равно | Проверят, меньше ли левое значение правому (или равно ему) | 3 | |
| >= | Больше или равно | Проверят, больше ли левое значение левого (или равно ему) | 5 >= 4 |
Примечание: вы можете заметить, что некоторые люди используют == и != в их программах для сравнения на равенство и неравенство — это валидные JavaScript-операторы, но они отличаются от === / !== — первая пара проверяет на равенство/неравенство значений, не рассматривая их типы. Вторая пара — строгая версия первой, которая проверяет типы операндов. При использовании строгой версии выявляется больше ошибок, поэтому мы рекомендуем использовать именно её.
Если вы попробуете использовать эти операторы в консоли, вы увидите, что все они возвращают значения true / false — о типе данных boolean мы писали в прошлой статье. С их помощью мы можем принимать решения в нашей программе, например:
- Порождать текст на кнопке в зависимости от того, нажата она или нет.
- Высвечивать сообщение о поражении при проигрыше или поздравление при победе в игре.
- Показывать пользователю верное окно приветствия в зависимости от времени года.
- Увеличивать или уменьшать карту при выборе одной из двух опций.
Мы взглянем на то, как реализовать такую логику после знакомства с условными выражениями в следующей статье. Сейчас мы рассмотрим небольшой пример:
button>Запустить машинуbutton> p>Машина остановленаp>
var btn = document.querySelector("button"); var txt = document.querySelector("p"); btn.addEventListener("click", updateBtn); function updateBtn() if (btn.textContent === "Start machine") btn.textContent = "Stop machine"; txt.textContent = "The machine has started!"; > else btn.textContent = "Start machine"; txt.textContent = "The machine id stopped."; > >
Мы использовали оператор равенства внутри функции updateBtn() . В этом случае мы не проверяем пару математических выражений на равенство значений — мы просто смотрим, является ли текст на кнопке определённой строкой — что по сути является тем же самым. Если кнопка при нажатии содержит «Start machine», мы меняем содержимое метки на «Stop machine» и обновляем метку. Если же текст кнопки — «Stop machine», при нажатии мы возвращаем все обратно.
Примечание: Такой элемент управления, который переключается между двумя состояниями, обычно называется тумблером. Он переключается между одним состоянием и другим: свет включён, свет выключен и т. д.
Итого
В этой статье мы привели основную информацию, необходимую для работы с числами в JavaScript. Вы постоянно будете использовать числа в процессе обучения языку, поэтому желательно разобраться в этом сейчас. Если вам действительно не нравится математика, пусть вас утешит, что эта статья была сравнительно короткой.
В следующей статье мы изучим текст и то, как мы работаем с ним в JavaScript.
Примечание: если вам хочется узнать подробнее о том, как математика реализуется в JavaScript, вы можете посмотреть главный раздел JavaScript MDN. Статьи Числа и даты и Выражения и операторы — хороший вариант для начала.
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 3 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Базовые операторы, математика
Многие операторы знакомы нам ещё со школы: сложение + , умножение * , вычитание — и так далее.
В этой главе мы начнём с простых операторов, а потом сконцентрируемся на специфических для JavaScript аспектах, которые не проходят в школьном курсе арифметики.
Термины: «унарный», «бинарный», «операнд»
Прежде, чем мы двинемся дальше, давайте разберёмся с терминологией.
- Операнд – то, к чему применяется оператор. Например, в умножении 5 * 2 есть два операнда: левый операнд равен 5 , а правый операнд равен 2 . Иногда их называют «аргументами» вместо «операндов».
- Унарным называется оператор, который применяется к одному операнду. Например, оператор унарный минус «-» меняет знак числа на противоположный:
let x = 1; x = -x; alert( x ); // -1, применили унарный минус
let x = 1, y = 3; alert( y - x ); // 2, бинарный минус вычитает значения
Математика
Поддерживаются следующие математические операторы:
- Сложение + ,
- Вычитание — ,
- Умножение * ,
- Деление / ,
- Взятие остатка от деления % ,
- Возведение в степень ** .
Первые четыре оператора очевидны, а про % и ** стоит сказать несколько слов.
Взятие остатка %
Оператор взятия остатка % , несмотря на обозначение, никакого отношения к процентам не имеет.
Результат a % b – это остаток от целочисленного деления a на b .
alert( 5 % 2 ); // 1, остаток от деления 5 на 2 alert( 8 % 3 ); // 2, остаток от деления 8 на 3 alert( 8 % 4 ); // 0, остаток от деления 8 на 4
Возведение в степень **
Оператор возведения в степень a ** b возводит a в степень b .
В школьной математике мы записываем это как a b .
alert( 2 ** 2 ); // 2² = 4 alert( 2 ** 3 ); // 2³ = 8 alert( 2 ** 4 ); // 2⁴ = 16
Математически, оператор работает и для нецелых чисел. Например, квадратный корень является возведением в степень ½:
alert( 4 ** (1/2) ); // 2 (степень 1/2 эквивалентна взятию квадратного корня)
Сложение строк при помощи бинарного +
Давайте рассмотрим специальные возможности операторов JavaScript, которые выходят за рамки школьной арифметики.
Обычно при помощи плюса ‘+’ складывают числа.
Но если бинарный оператор ‘+’ применить к строкам, то он их объединяет в одну:
let s = "моя" + "строка"; alert(s); // моястрока
Обратите внимание, если хотя бы один операнд является строкой, то второй будет также преобразован в строку.
alert( '1' + 2 ); // "12" alert( 2 + '1' ); // "21"
Как видите, не важно, первый или второй операнд является строкой.
Вот пример посложнее:
alert(2 + 2 + '1' ); // будет "41", а не "221"
Здесь операторы работают один за другим. Первый + складывает два числа и возвращает 4 , затем следующий + объединяет результат со строкой, производя действие 4 + ‘1’ = ’41’ .
Сложение и преобразование строк — это особенность бинарного плюса + . Другие арифметические операторы работают только с числами и всегда преобразуют операнды в числа.
Например, вычитание и деление:
alert( 6 - '2' ); // 4, '2' приводится к числу alert( '6' / '2' ); // 3, оба операнда приводятся к числам
Приведение к числу, унарный +
Плюс + существует в двух формах: бинарной, которую мы использовали выше, и унарной.
Унарный, то есть применённый к одному значению, плюс + ничего не делает с числами. Но если операнд не число, унарный плюс преобразует его в число.
// Не влияет на числа let x = 1; alert( +x ); // 1 let y = -2; alert( +y ); // -2 // Преобразует не числа в числа alert( +true ); // 1 alert( +"" ); // 0
На самом деле это то же самое, что и Number(. ) , только короче.
Необходимость преобразовывать строки в числа возникает очень часто. Например, обычно значения полей HTML-формы — это строки. А что, если их нужно, к примеру, сложить?
Бинарный плюс сложит их как строки:
let apples = "2"; let oranges = "3"; alert( apples + oranges ); // "23", так как бинарный плюс объединяет строки
Поэтому используем унарный плюс, чтобы преобразовать к числу:
let apples = "2"; let oranges = "3"; // оба операнда предварительно преобразованы в числа alert( +apples + +oranges ); // 5 // более длинный вариант // alert( Number(apples) + Number(oranges) ); // 5
С точки зрения математика, такое изобилие плюсов выглядит странным. Но с точки зрения программиста тут нет ничего особенного: сначала выполнятся унарные плюсы, которые приведут строки к числам, а затем бинарный ‘+’ их сложит.
Почему унарные плюсы выполнились до бинарного сложения? Как мы сейчас увидим, дело в их приоритете.
Приоритет операторов
В том случае, если в выражении есть несколько операторов – порядок их выполнения определяется приоритетом, или, другими словами, существует определённый порядок выполнения операторов.
Из школы мы знаем, что умножение в выражении 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 .
let x = 2 * 2 + 1; alert( x ); // 5
Присваивание = возвращает значение
Тот факт, что = является оператором, а не «магической» конструкцией языка, имеет интересные последствия.
Большинство операторов в JavaScript возвращают значение. Для некоторых это очевидно, например сложение + или умножение * . Но и оператор присваивания не является исключением.
Вызов x = value записывает value в x и возвращает его.
Благодаря этому присваивание можно использовать как часть более сложного выражения:
let a = 1; let b = 2; let c = 3 - (a = b + 1); alert( a ); // 3 alert( c ); // 0
В примере выше результатом (a = b + 1) будет значение, которое присваивается переменной a (то есть 3 ). Потом оно используется для дальнейших вычислений.
Забавное применение присваивания, не так ли? Нам нужно понимать, как это работает, потому что иногда это можно увидеть в JavaScript-библиотеках.
Однако писать самим в таком стиле не рекомендуется. Такие трюки не сделают ваш код более понятным или читабельным.
Присваивание по цепочке
Рассмотрим ещё одну интересную возможность: цепочку присваиваний.
let a, b, c; a = b = c = 2 + 2; alert( a ); // 4 alert( b ); // 4 alert( c ); // 4
Такое присваивание работает справа налево. Сначала вычисляется самое правое выражение 2 + 2 , и затем результат присваивается переменным слева: c , b и a . В конце у всех переменных будет одно значение.
Опять-таки, чтобы код читался легче, лучше разделять подобные конструкции на несколько строчек:
c = 2 + 2; b = c; a = c;
Польза от такого стиля особенно ощущается при быстром просмотре кода.
Сокращённая арифметика с присваиванием
Часто нужно применить оператор к переменной и сохранить результат в ней же.
let n = 2; n = n + 5; n = n * 2;
Эту запись можно укоротить при помощи совмещённых операторов += и *= :
let n = 2; n += 5; // теперь n = 7 (работает как n = n + 5) n *= 2; // теперь n = 14 (работает как n = n * 2) alert( n ); // 14
Подобные краткие формы записи существуют для всех арифметических и побитовых операторов: /= , -= , **= и так далее.
Вызов с присваиванием имеет в точности такой же приоритет, как обычное присваивание, то есть выполнится после большинства других операций:
let n = 2; n *= 3 + 5; alert( n ); // 16 (сначала выполнится правая часть, выражение идентично n *= 8)
Инкремент/декремент
Одной из наиболее частых числовых операций является увеличение или уменьшение на единицу.
Для этого существуют даже специальные операторы:
-
Инкремент ++ увеличивает переменную на 1:
let counter = 2; counter++; // работает как counter = counter + 1, просто запись короче alert( counter ); // 3
let counter = 2; counter--; // работает как counter = counter - 1, просто запись короче alert( counter ); // 1
Инкремент/декремент можно применить только к переменной. Попытка использовать его на значении, типа 5++, приведёт к ошибке.
Операторы ++ и — могут быть расположены не только после, но и до переменной.
- Когда оператор идёт после переменной — это «постфиксная форма»: counter++ .
- «Префиксная форма» — это когда оператор идёт перед переменной: ++counter .
Обе эти инструкции делают одно и то же: увеличивают counter на 1 .
Есть ли разница между ними? Да, но увидеть её мы сможем, только если будем использовать значение, которое возвращают ++/— .
Давайте проясним этот момент. Как мы знаем, все операторы возвращают значение. Операторы инкремента/декремента не исключение. Префиксная форма возвращает новое значение, в то время как постфиксная форма возвращает старое (до увеличения/уменьшения числа).
Чтобы увидеть разницу, вот небольшой пример:
let counter = 1; let a = ++counter; // (*) alert(a); // 2
В строке (*) префиксная форма ++counter увеличивает counter и возвращает новое значение 2 . Так что alert покажет 2 .
Теперь посмотрим на постфиксную форму:
let counter = 1; let a = counter++; // (*) меняем ++counter на counter++ alert(a); // 1
В строке (*) постфиксная форма counter++ также увеличивает counter , но возвращает старое значение (которое было до увеличения). Так что alert покажет 1 .
-
Если результат оператора не используется, а нужно только увеличить/уменьшить переменную, тогда без разницы, какую форму использовать:
let counter = 0; counter++; ++counter; alert( counter ); // 2, обе строки сделали одно и то же
