Деление по модулю javascript. Арифметические операции в JavaScript

Деление по модулю javascript. Арифметические операции в JavaScript

Напоминаю, что это вводный курс по JavaScript для начинающих . Сегодня мы рассмотрим, какие операторы существуют в JavaScript . Пристегните ремни! Букаф будет много.

Когда у вас есть кучка данных, то с ними нужно что-то сделать. Делами-то как раз и заняты операторы. Они вечно что-то складывают, перемножают, делят, отнимают, сравнивают, присваивают и еще черти чем занимаются. Без операторов в программировании просто каши не сваришь.

В языке JavaScript используются следующие виды операторов:

  • Арифметические операторы
  • Операторы присваивания
  • Операторы сравнения
  • Логические операторы
  • Строковые операторы
  • Условные операторы

Это далеко не полный список, но для начала хватит и этого за глаза. Разберем каждый вид представленных операторов, зачем они нужны и с чем их едят. Поехали!

Арифметические операторы в JavaScript

С арифметическими операторами все вы знакомы еще со школы. Это обычные знаки сложения, вычитания, деления и умножения: + , - , / , * . Соответственно, выполняют они в программировании те же самые функции, что и в обычной математике. Сложностей с этим у вас не возникнет.

Данные, с которыми работают операторы, называются операндами .

2 + 3 // здесь числа 2 и 3 - операнды, а знак + - оператор сложения

Как и в математике у арифметических операторов есть свои приоритеты: умножение и деление имеют более высокий приоритет, чем сложение и вычитание.

2 + 3 * 4 // здесь сначала выполняется умножение, а уже потом сложение

И так же, как в математике, активно используются скобки, чтобы изменить приоритет:

(2 + 3) * 4 // здесь сначала выполняется сложение, а потом умножение

Кстати, знак = тоже оператор. Как мы уже выяснили в статье про , это оператор присваивания, а вовсе не знак равенства. Не забывайте об этом!

Оператор деления по модулю

А теперь рассмотрим более интересные арифметические операторы. И первым станет значок процентов - % . В JavaScript это не проценты от слова совсем. Так в программировании обозначается деление по модулю. Результатом такой операции будет остаток от деления. Например:

100 % 22 // остаток будет равен 12
100 % 10 // остаток будет равен 0

При вычислениях этот оператор имеет тот же приоритет, что и умножение с делением, так что не забывайте ставить скобочки.

Совмещение операторов

Оператор = можно и нужно совмещать с другими операторами, чтобы сократить запись. Пример:

var n = 2; // присваиваем переменной n значение 2
n = n + 3; // присваиваем переменной n новое значение n + 2, получаем 5

То же самое можно записать так:

var n = 2;
n += 3; // равносильно записи n = n + 3

Операторы инкремента ++ и декремента – –

Среди арифметических операторов есть парочка весьма любопытных - инкремент и декремент . Обозначаются соответственно ++ и –– . Первый увеличивает переменную на единицу, а второй уменьшает. Эта фишка очень часто используется в программировании, так как предоставляет массу удобств. Чаще всего ее можно встретить в условных выражениях, но об этом позже.

У обоих операторов есть определенное местоположение в записи. Они могут быть как в префиксной форме (перед переменной) ++n , так и в постфиксной (после переменной) n++ . Разница огромна! Никогда не путайте эти формы и хорошенько запомните их. Если эти операторы стоят перед переменной, то в результате увеличивают ее значение на 1. Но! Если они стоят после переменной, то возвращают исходное значение. Пример:

var n = 2, m = 0;
m = ++n // увеличивает n на 1 (n = 3) и присваивает m тоже значение 3

var n = 2, m = 3;
m = n++ // увеличивает n на 1 (n = 3), но присваивает m предыдущее значение n = 2

С первым примером, уверен, вы легко разберетесь. А вот со вторым могут возникнуть проблемы. Чтобы легче было понять эту штуку и не запутаться, просто представьте, что вы сначала присвоили переменной m значение переменной n , а уже после этого увеличили значение n на единицу. В первом же примере вы сначала увеличили значение n на единицу, а потом уже присвоили это значение переменной m .

На этом с арифметическими операторами все. Разумеется, есть еще куча вариаций и тонкостей использования этих простых операторов, но для начала вам этого будет более чем достаточно.

Операторы сравнения

И снова вспоминаем математику. Знаки знакомы всем и каждому. В программировании они называются операторами сравнения . В JavaScript используются следующие операторы сравнения:

< меньше
> больше
= больше или равно
== равно
!= не равно
=== строго равно
!== строго не равно

Обратите внимание, что знак «больше или равно» пишется именно так >= , а не => . То есть, стрелка стоит перед знаком равно, а не после него.

Операторы сравнения позволяют сравнивать значения переменных и результатом этой операции всегда выступает булево значение true или false . Обычно их применяют в условных выражениях. От того, что дает результат сравнение зависит, какая часть кода будет выполняться дальше.

В JavaScript можно сравнивать разные типы данных одновременно, например, число и строку:

12345 == "12345" // true

Просто в этом случае строка автоматически преобразуется в число. Строгое же равенство === или неравенство!== используются только при сравнении переменных одинакового типа.

Логические операторы

Логические операции в JavaScript - это одна из довольно мудреных тем для начинающих. С ней стоит хорошенько разобраться, чтобы успешно идти дальше в освоении языка. Они чаще всего применяются вместе с операциями сравнения и выдают булево значение true или false .

Логических операторов три:

&& (И)
|| (ИЛИ)
! (НЕ)

Логический оператор && (И)

Оператор && выполняет операцию «логическое И» над двумя значениями. При этом он возвращает true тогда и только тогда, когда оба операнда имеют значение true . Если же один или оба операнда имеют значение false , то оператор возвращает false . Примеры:

2 < 3 && 4 < 5 // true
2 < 3 && 5 < 4 // false
3 < 2 && 5 < 4 // false

У логических операторов приоритет меньше, чем у операторов сравнения, поэтому в приведенных примерах мы обходимся без скобок. Понятно, что сначала мы сравниваем числа между собой, а уже потом применяем логику.

Логический оператор || (ИЛИ)

С логическим оператором || (ИЛИ) другая песня. Оператор || выполняет операцию «логическое ИЛИ» над двумя операндами. Если один или оба операнда имеют истинное значение, он возвращает истинное значение. Если оба операнда имеют ложные значения, он возвращает ложное значение. Примеры:

2 < 3 || 4 < 5 // true
2 < 3 || 5 < 4 // true
3 < 2 || 5 < 4 // false

У логических операторов есть одна хитрость. Они не любят лишней работы. Как, впрочем, и я. Свои вычисления они всегда начинают слева направо. И если первая часть выражения соответствует их условиям, то остальную часть выражения они даже не вычисляют.

К примеру, если оператор || находит истинное значение в самом начале, то сразу дает истинное значение, а остальное уже не проверяет. Также и оператор && , если находит в самом начале ложное выражение, то сразу дает ложный результат, а остальную часть не проверяет.

И еще одна фишка: приоритет у оператора И && больше, чем у ИЛИ || , поэтому он выполняется раньше:

2 < 3 || 4 < 5 && 5 < 6 // здесь сначала будет выполнено вычисление в правой части, а потом уже в левой

Логический оператор! (НЕ)

Логический оператор! обозначает «логическое НЕ». Он используется только с одним операндом и меняет значение этого операнда на противоположное. Если значение n истинно, то значение!n будет ложным. Так как этот оператор можно прикрутить лишь к одному операнду, то чтобы инвертировать целое выражение, его надо взять в скобки!(n && m) .

Строковые операторы

Про строковые операторы мы уже говорили ранее. Это тот самый плюс + что используется для соединения строковых переменных, или иначе - для конкатенации (сложения строк). Пример:

"Игорь " + "Квентор" == "Игорь Квентор"

Обратите внимание, что в первом слове добавлен пробел перед закрывающей кавычкой. Если его не добавить, то строки сольются в одно слово "ИгорьКвентор" .

У этого оператора есть одна особенность: если в выражении есть хоть одна строка, то он и все остальные аргументы приводит к строковому типу. Например:

Остальные арифметические операторы работают только с числами и всегда приводят аргументы к числу.

Условные операторы

В JavaScript есть два условных оператора if и?: Хотя, если быть точным, то if - это вообще-то управляющая инструкция и довольно обширная, с кучей плюшек и интересных особенностей. Поэтому о ней будет отдельная статья. Пока же рассмотрим более простой условный оператор?:

Обычно этот оператор записывается как?: Но в программах он выглядит иначе. Он имеет три операнда. Первый операнд предшествует символу? , второй стоит между символами? и: третий - после:

условие? значение 1: значение 2

Смысл его работы прост: если выполняется поставленное условие, то возвращается значение 1, если же нет - значение 2. Этот условный оператор часто служит более простой заменой инструкции if , когда в последней нет особой необходимости. При этом и сама запись сокращается и ее легче прочесть.

Пока на этом все!

Надеюсь, с операторам в JavaScript вы теперь немного разобрались. А чтобы мозг не закипел, вот вам короткий мульт для расслабления - Программист может все! :)

Очень часто вычисления в JavaScript дают не совсем те результаты, которые мы хотим. Разумеется, мы можем делать с числами что угодно - округлять в большую или меньшую сторону, устанавливать диапазоны, отсекать ненужные числа до определенного количества знаков после запятой, все зависит от того, что вы хотите сделать в дальнейшем с этим числом. Зачем необходимо округление? Одним из любопытных аспектов JavaScript является то, что он на самом деле не хранит целые числа, мы сразу же работаем с числами с плавающей точкой. Это, в сочетании с тем фактом, что многие дробные значения не могут быть выражены конечным числом знаков после запятой, в JavaScript мы можем получить такие результаты:

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
Для практических целей эта неточность не имеет никакого значения, в нашем случае мы говорим об ошибке в квинтиллионных долях, однако, кого-то это может разочаровать. Мы можем получить несколько странный результат и при работе с числами, которые представляют собой значения валют, процентов или размеров файла. Для того, чтобы исправить эти неточности, нам как раз и необходимо уметь округлять результаты, при этом достаточно установить десятичную точность.

Округление чисел имеет практическое применение, мы можем манипулировать числом в некотором диапазоне, например, хотим округлить значение до ближайшего целого числа, а не работать только с десятичной частью.

Округление десятичных чисел Для того, чтобы отсечь десятичное число, используйте toFixed или метод toPrecision . Оба они принимают единственный аргумент, который определяет, соответственно, сколько значащих цифр (т.е. общее количество цифр, используемых в числе) или знаков после запятой (количество после десятичной точки) должен включать в себя результат:
  • Если аргумент не определен для toFixed(), то по умолчанию он будет равен нулю, что означает 0 знаков после запятой, аргумент имеет максимальное значение, равное 20.
  • Если аргумент не задан для toPrecision, число остается нетронутым
  • let randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" randNum = 87.335; randNum.toFixed(2); > "87.33" randNum = 87.337; randNum.toPrecision(3); > "87.3"
    Оба метода toFixed() и toPrecision() возвращают строковое представление результата, а не число. Это означает, что при суммировании округленного значения с randNum будет произведена конкатенация строк, а не сумма чисел:

    Let randNum = 6.25; let rounded = randNum.toFixed(); // "6" console.log(randNum + rounded); > "6.256"
    Если вы хотите, чтобы результат имел числовой тип данных, то вам необходимо будет применить parseFloat:

    Let randNum = 6.25; let rounded = parseFloat(randNum.toFixed(1)); console.log(rounded); > 6.3
    Обратите внимание, что значения 5 округлены, за исключением редких случаев.

    Методы toFixed() и toPrecision() являются полезными, ибо они могут не только отсекать дробную часть, но и дополнять знаки после запятой, что удобно при работе с валютой:

    Let wholeNum = 1 let dollarsCents = wholeNum.toFixed(2); console.log(dollarsCents); > "1.00"
    Стоить обратите внимание, что toPrecision будет давать результат в экспоненциальной записи, если число целых чисел больше, чем сам сама точность:

    Let num = 123.435 num.toPrecision(2); > "1.2e+2"

    Как избежать ошибок округления с десятичными числами В некоторых случаях, toFixed и toPrecision округляет значение 5 в меньшую сторону, а в большую:

    Let numTest = 1.005; numTest.toFixed(2); > "1.00"
    Результат расчета выше должен был быть 1.01, а не 1. Если вы хотите избежать подобную ошибку, мы можем использовать решение, предложенное Jack L Moore , которое использует экспоненциальные числа для расчета:

    Function round(value, decimals) { return Number(Math.round(value+"e"+decimals)+"e-"+decimals); }
    Теперь:

    Round(1.005,2); > 1.01
    Если вы хотите более надежное решение, чем решение показанное выше, вы можете перейти на MDN .

    Машинное эпсилон округление Альтернативный метод округления десятичных чисел был введен в ES6. Машинное эпсилон округление обеспечивает разумный предел погрешности при сравнении двух чисел с плавающей точкой. Без округления, сравнения могут дать результаты, подобные следующим:

    0.1 + 0.2 === 0.3 > false
    Мы используем Math.EPSILON в нашей функции для получения корректного сравнения:

    Function epsEqu(x, y) { return Math.abs(x - y) < Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
    Функция принимает два аргумента: первый - текущий расчет, второй - ожидаемый результат. Она возвращает сравнение двух:

    EpsEqu(0.1 + 0.2, 0.3) > true
    Все современные браузеры уже поддерживают ES6 математические функции, но если вы хотите получить поддержку в таких браузерах, как IE 11, используйте polyfills .

    Отсечение дробной части Все методы, представленные выше умеют округлять до десятичных чисел. Для того, чтобы просто отсечь число до двух знаков после запятой, необходимо сначала умножить его на 100, а затем полученный результат уже разделить на 100:

    Function truncated(num) { return Math.trunc(num * 100) / 100; } truncated(3.1416) > 3.14
    Если вы хотите приспособить метод под любое количество знаков после запятой, вы можете воспользоваться двойным побитовым отрицанием :

    Function truncated(num, decimalPlaces) { let numPowerConverter = Math.pow(10, decimalPlaces); return ~~(num * numPowerConverter)/numPowerConverter; }
    Теперь:

    Let randInt = 35.874993; truncated(randInt,3); > 35.874

    Округление до ближайшего числа Для того, чтобы округлить десятичное число до ближайшего числа в большую или в меньшую сторону, в зависимости от того, к чему мы ближе всего, используйте Math.round():

    Math.round(4.3) > 4 Math.round(4.5) > 5
    Обратите внимание, что «половина значения», 0.5 округляется в большую сторону по правилам математики .

    Округление к меньшему до ближайшего целого числа Если вы хотите всегда округлять в меньшую сторону, используйте Math.floor:

    Math.floor(42.23); > 42 Math.floor(36.93); > 36
    Обратите внимание, что округление в меньшую сторону работает для всех чисел, в том числе и для отрицательных. Представьте небоскреб с бесконечным количеством этажей, в том числе с этажами нижнего уровня (представляющий отрицательные числа). Если вы находитесь в лифте на нижним уровнем между 2 и 3 (что представляет собой значение -2.5), Math.floor доставит вас до -3:

    Math.floor(-2.5); > -3
    Но если вы хотите избежать подобной ситуации, используйте Math.trunc , поддерживаемый во всех современных браузерах (кроме IE / Edge):

    Math.trunc(-41.43); > -41
    На MDN вы найдете polyfill, который обеспечит поддержку Math.trunc в браузерах и IE / Edge.

    Округление к большему до ближайшего целого числа С другой стороны, если вам нужно всегда округлять в большую сторону, используйте Math.ceil. Опять же, вспоминаем бесконечный лифт: Math.ceil всегда будет идти «вверх», независимо от того, является ли число отрицательное или нет:

    Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); > -36

    Округление до большего/меньшего необходимого числа Если мы хотим, чтобы округлить до ближайшего числа, кратного 5, самый простой способ создать функцию, которая делит число на 5, округляет его, а затем умножает его на ту же сумму:

    Function roundTo5(num) { return Math.round(num/5)*5; }
    Теперь:

    RoundTo5(11); > 10
    Если вы хотите округлять до кратных своему значению, мы использовать более общую функцию, передавая в нее начальное значение и кратное:

    Function roundToMultiple(num, multiple) { return Math.round(num/multiple)*multiple; }
    Теперь:

    Let initialNumber = 11; let multiple = 10; roundToMultiple(initialNumber, multiple); > 10;

    Фиксирование числа в диапазоне Есть много случаев, когда мы хотим получить значение х, лежащее в пределах диапазона. Например, нам может понадобиться значение от 1 до 100, но при этом мы получили значение 123. Для того, чтобы исправить это, мы можем использовать минимальное (возвращает наименьшее из набора чисел) и максимальное (возвращает наибольшее из любого множества чисел). В нашем примере, диапазон от 1 до 100:

    Let lowBound = 1; let highBound = 100; let numInput = 123; let clamped = Math.max(lowBound, Math.min(numInput, highBound)); console.log(clamped); > 100;
    Опять же, мы можем переиспользовать операцию и обернуть все это в функцию, воспользуемся решением предложенное Daniel X. Moore :

    Number.prototype.clamp = function(min, max) { return Math.min(Math.max(this, min), max); };
    Теперь:

    NumInput.clamp(lowBound, highBound); > 100;

    Гауссово округление Гауссово округление, также известное как банковское округлением, заключается в том, что округление для этого случая происходит к ближайшему чётному. Этот метод округления работает без статистической погрешности. Лучшее решение было предложено Tim Down :

    Function gaussRound(num, decimalPlaces) { let d = decimalPlaces || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor(n), f = n - i, e = 1e-8, r = (f > 0.5 - e && f < 0.5 + e) ? ((i % 2 == 0) ? i: i + 1) : Math.round(n); return d ? r / m: r; }
    Теперь:

    GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
    Десятичный знак в CSS:

    Так как JavaScript часто используется для создания позиционного преобразования HTML-элементов, вы можете задаться вопросом, что произойдет, если мы cгенерируем десятичные значения для наших элементов:

    #box { width: 63.667731993px; }
    Хорошая новость заключается в том, что современные браузеры будут учитывать десятичные значения в блочной модели, в том числе в процентных или пиксельных единицах измерения.

    Сортировка Очень часто нам приходится сортировать какие-либо элементы, например, у нас есть массив игровых рекордов, при этом они должны быть организованы по убыванию ранга игроков. К сожалению, стандартный метод sort() имеет некоторые удивительные ограничения: он хорошо работает с часто употребляемыми английскими словами, но сразу же ломается при встрече с числами, уникальными символами или словами в верхнем регистре. Сортировка в алфавитном порядке Казалось бы, сортировки массива по алфавиту должна быть простейшей задачей:

    Let fruit = ["butternut squash", "apricot", "cantaloupe"]; fruit.sort(); > "apricot", "butternut squash", "cantaloupe"]
    Тем не менее мы сталкиваемся с проблемой, как только один из элементов находится в верхнем регистре:

    Let fruit = ["butternut squash", "apricot", "Cantalope"]; fruit.sort(); > "Cantaloupe", "apricot", "butternut squash"]
    Это связано с тем, что, по умолчанию, сортировщик сравнивает первый символ представленный в Unicode . Unicode - это уникальный код для любого символа, независимо от платформы, независимо от программы, независимо от языка. Например, если смотреть по кодовой таблице символ «a» имеет значение U+0061 (в шестнадцатеричной системе 0x61), в то время как символ «C» имеет код U+0043 (0x43), который идет раньше в Unicode-таблице, чем символ «a».

    Чтобы отсортировать массив, который может содержать смешанные регистры первых букв, нам необходимо либо преобразовать все элементы временно в нижний регистру, или определить свой порядок сортировки при помощи метода localeCompare() c некоторыми аргументами. Как правило, для такого случая, лучше сразу создать функцию для многократного использования:

    Function alphaSort(arr) { arr.sort(function (a, b) { return a.localeCompare(b, "en", {"sensitivity": "base"}); }); } let fruit = ["butternut squash", "apricot", "Cantaloupe"]; alphaSort(fruit) >
    Если вы хотите получить массив отсортированный в обратный алфавитном порядке, просто поменяйте позициями а и b в функции:

    Function alphaSort(arr) { arr.sort(function (a, b) { return b.localeCompare(a, "en", {"sensitivity": "base"}); }); } let fruit = ["butternut squash", "apricot", "Cantaloupe"]; alphaSort(fruit) > ["Cantaloupe", "butternut squash", "apricot"]
    Тут стоит обратить внимание, что localeCompare используется с аргументами, еще надо помнить, что он поддерживается IE11+, для более старых версий IE, мы можем использовать его без аргументов, и в нижнем регистре:

    Function caseSort(arr) { arr.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); } let fruit = ["butternut squash", "apricot", "Cantaloupe"]; caseSort(fruit) > ["apricot", "butternut squash", "Cantaloupe"]

    Числовая сортировка Все это не относится к тому примеру, о котором мы говорили выше про массив игровых рекордов. С некоторыми числовыми массивами сортировка работает просто идеально, но в какой-то момент результат может быть непредсказуемым:

    Let highScores = ; highScores.sort(); >
    Дело в том, что метод sort() производит лексикографическую сравнение : а это означает, что числа будут преобразованы в строку и сравнения будут снова проводиться путем сопоставления первого символа этой строки в порядке символов Unicode-таблицы. Поэтому нам снова необходимо определить свой порядок сортировки:

    Let highScores = ; highScores.sort(function(a,b) { return a - b; }); >
    Опять же, для сортировки чисел в обратном порядке, поменяйте позициями a и b в функции.

    Сортировка JSON-подобной структуры И наконец, если у нас есть JSON-подобная структура данных , представленная как массив игровых рекордов:

    Let scores = [ { "name": "Daniel", "score": 21768 }, { "name": "Michael", "score": 33579 }, { "name": "Alison", "score": 38395 } ];
    В ES6+, вы можете использовать стрелочные функции:

    Scores.sort((a, b) => b.score - a.score));
    Для старых браузеров, не имеющих такую поддержку:

    Scores.sort(function(a, b) { return a.score - b.score });
    Как видите, сортировка в JavaScript это довольно не очевидная вещь, я надеюсь, что эти примеры облегчат как-нибудь жизнь.

    Работа со степенными функциями Возведение в степень - операция, первоначально определяемая как результат многократного умножения натурального числа на себя, квадратный корень из числа a - число, дающее a при возведении в квадрат. Этими функциями мы могли пользоваться постоянно в повседневной жизни на уроках математики, в том числе при вычислении площадей, объемов или даже при физическом моделировании.

    В JavaScript степенная функция представлена как Math.pow(), в новом стандарте ES7 был представлен новый оператор возведения в степень - " * * ".

    Возведение в степень Для того, чтобы возвести число в n-ую степень, используйте функцию Math.pow(), где первый аргумент это число, которое будет возведено в степень, второй аргумент это показатель степени:

    Math.pow(3,2) > 9
    Такая форма записи означает 3 в квадрате, или 3 × 3, что приводит к результату 9. Можно привести еще пример, конечно:

    Math.pow(5,3); > 125
    То есть, 5 в кубе, или 5 × 5 × 5, равно 125.

    ECMAScript 7 - это следующая версия JavaScript, в принципе, мы можем использовать новый предложенный оператор возведения в степень - * *, такая форма записи может быть более наглядной:

    3 ** 2 > 9
    На данный момент поддержка этого оператора довольно ограниченная , поэтому его не рекомендуется использовать.

    Степенная функция может пригодиться в самых разных ситуациях. Простой пример, вычисление количества секунд в часе: Math.pow (60,2).

    Квадратный и кубический корень Math.sqrt() и Math.cbrt() противоположны функции Math.pow(). Как мы помним, квадратный корень из числа a - число, дающее a при возведении в квадрат.

    Math.sqrt(9) > 3
    В тоже время кубический корень из числа a - число, дающее a при возведении в куб.

    Math.cbrt(125) > 5
    Math.cbrt() был введен в спецификацию JavaScript совсем недавно, и поэтому поддерживается только в современных браузерах: Chrome 38+, Firefox и Opera 25+ и Safari 7.1+. Вы заметите, что Internet Explorer отсутствует в этом списке, однако на MDN вы найдете полифилл .

    Примеры Конечно, мы можем использовать и не целые значения в одной из этих функций:

    Math.pow(1.25, 2); > 1.5625 Math.cbrt(56.57) > 3.8387991760286138
    Обратите внимание, что это вполне себе работает и при использовании отрицательных значениях аргументов:

    Math.pow(-5,2) > 25 Math.pow(10,-2) > 0.01
    Тем не менее, для квадратного корня это не будет работать:

    Math.sqrt(-9) > NaN
    Из математического анализа мы знаем, что под мнимым числом понимают квадратные корни из отрицательных чисел. И это может привести нас к еще одной технике работы с комплексными числами, но это уже другая история.

    Вы можете использовать дробные значения в Math.pow(), чтобы найти квадратные и кубические корни чисел. Квадратный корень использует показатель 0.5:

    Math.pow(5, 0.5); // = Math.sqrt(5) = 5 ** (1/2) > 2.23606797749979
    Однако, из-за капризов с плавающей точкой, вы не можете точно предположить правильный результат:

    Math.pow(2.23606797749979,2) > 5.000000000000001
    В таких ситуациях, вы вам придется прибегать к отсечению знаков у числа или округление до какого-либо значения.

    Некоторые, по непонятным причинам в JavaScript путают функцию Math.pow() с Math.exp() , которая является экспоненциальной функцией для чисел, в целом. Примечание: в английском языке «показатель степени» переводится как «exponent», поэтому это скорее относится к англоговорящим, хотя существуют и альтернативные названия показателя степени , такие как index, power.

    Математические константы Работа с математикой в JavaScript облегчается за счет ряда встроенных констант. Эти константы являются свойствами объекта Math. Стоит обратить внимание, что константы пишутся в верхнем регистре, а не CamelCase нотации.

    Только зарегистрированные пользователи могут участвовать в опросе. , пожалуйста.

    Теги: Добавить метки

    Последнее обновление: 1.11.2015

    Математические операции

    JavaScript поддерживает все базовые математические операции:

    Сложение :

    Var x = 10; var y = x + 50;

    Вычитание :

    Var x = 100; var y = x - 50;

    Умножение :

    Var x = 4; var y = 5; var z = x * y;

    Деление :

    Var x = 40; var y = 5; var z = x / y;

    Деление по модулю (оператор %) возвращает остаток от деления:

    Var x = 40; var y = 7; var z = x % y; console.log(z); // 5

    Результатом будет 5, так как наибольшее целое число, которое меньше или равно 40 и при этом делится на 7 равно 35, а 40 - 35 = 5.

    Инкремент :

    Var x = 5; x++; // x = 6

    Оператор инкремента ++ увеличивает переменную на единицу. Существует префиксный инкремент, который сначала увеличивает переменную на единицу, а затем возвращает ее значение. И есть постфиксный инкремент, который сначала возвращает значение переменной, а затем увеличивает его на единицу:

    // префиксный инкремент var x = 5; var z = ++x; console.log(x); // 6 console.log(z); // 6 // постфиксный инкремент var a = 5; var b = a++; console.log(a); // 6 console.log(b); // 5

    Постфиксный инкремент аналогичен операции:

    A = a + 1; // a++

    Декремент уменьшает значение переменной на единицу. Также есть префиксный и постфиксный декремент:

    // префиксный декремент var x = 5; var z = --x; console.log(x); // 4 console.log(z); // 4 // постфиксный декремент var a = 5; var b = a--; console.log(a); // 4 console.log(b); // 5

    Как и принято в математике, все операции выполняются слева направо и различаются по приоритетам: сначала операции инкремента и декремента, затем выполняются умножение и деление, а потом сложение и вычитание. Чтобы изменить стандартный ход выполнения операций, часть выражений можно поместить в скобки:

    Var x = 10; var y = 5 + (6 - 2) * --x; console.log(y); //41

    Операции присваивания

      Приравнивает переменной определенное значение: var x = 5;

      Сложение с последующим присвоением результата. Например:

      Var a = 23; a += 5; // аналогично a = a + 5 console.log(a); // 28

      Вычитание с последующим присвоением результата. Например:

      Var a = 28; a -= 10; // аналогично a = a - 10 console.log(a); // 18

      Умножение с последующим присвоением результата:

      Var x = 20; x *= 2; // аналогично x = x * 2 console.log(x); // 40

      Деление с последующим присвоением результата:

      Var x = 40; x /= 4; // аналогично x = x / 4 console.log(x); // 10

      Получение остатка от деления с последующим присвоением результата:

      Var x = 10; x %= 3; // аналогично x = x % 3 console.log(x); // 1, так как 10 - 3*3 = 1

    Операторы сравнения

    Как правило, для проверки условия используются операторы сравнения. Операторы сравнения сравнивают два значения и возвращают значение true или false:

      Оператор равенства сравнивает два значения, и если они равны, возвращает true, иначе возвращает false: x == 5

      Оператор тождественности также сравнивает два значения и их тип, и если они равны, возвращает true, иначе возвращает false: x === 5

      Сравнивает два значения, и если они не равны, возвращает true, иначе возвращает false: x != 5

      Сравнивает два значения и их типы, и если они не равны, возвращает true, иначе возвращает false: x !== 5

      Сравнивает два значения, и если первое больше второго, то возвращает true, иначе возвращает false: x > 5

      Сравнивает два значения, и если первое меньше второго, то возвращает true, иначе возвращает false: x < 5

      Сравнивает два значения, и если первое больше или равно второму, то возвращает true, иначе возвращает false: x >= 5

      Сравнивает два значения, и если первое меньше или равно второму, то возвращает true, иначе возвращает false: x 50 && percent < 12; console.log(result); //true

      Возвращает true, если хотя бы одна операция сравнения возвращают true, иначе возвращает false:

      Var income = 100; var isDeposit = true; var result = income > 50 || isDeposit == true; console.log(result); //true

      Возвращает true, если операция сравнения возвращает false:

      Var income = 100; var result1 = !(income > 50); console.log(result1); // false, так как income > 50 возвращает true var isDeposit = false; var result2 = !isDeposit; console.log(result2); // true

    Операции со строками

    Строки могут использовать оператор + для объединения. Например:

    Var name = "Том"; var surname = "Сойер" var fullname = name + " " + surname; console.log(fullname); //Том Сойер

    Если одно из выражений представляет строку, а другое - число, то число преобразуется к строке и выполняется операция объединения строк:

    Var name = "Том"; var fullname = name + 256; console.log(fullname); //Том256

    В конце напишем небольшую программу, которая продемонстрирует работу с операциями над переменными. Для этого определим следующую веб-страницу index.html:

    JavaScript var sum = 500; // сумма вклада var percent = 10; // процент по вкладу var income = sum * percent / 100; // доход по вкладу sum = sum + income; // определяем новую сумму console.log("Доход по вкладу: " + income); console.log("Сумма вклада после первого года: " + sum);

    В скрипте объявляются три переменных: sum, percent и income. Переменная income вычисляется по остальным двум переменным с помощью операций умножения и деления. И в конце ее значение суммируется с значением переменной sum.

    Если вы новичок в JavaScript, то такой жаргон как "modle bundlers vs. module loaders", "Webpack vs. Browserify" и "AMD vs. CommonJS" может поставить вас в тупик.

    Система модулей в JavaScript может быть пугающей, но её понимание жизненно важно для разработчиков.

    В этой статье я постараюсь объяснить всё простыми словами (с несколькими примерами кода). Надеюсь, что для вас эта статья окажется полезной.

    Примечание: Для удобства статья будет разделена на две части. В первой части мы рассмотрим, что такое модули и почему мы их используем. Во второй части мы рассмотрим различные способы объединения модулей в единое целое.

    Кто-нибудь объясните, что такое модули ещё раз?

    Также как и главы книги, модули это просто кластеры слов (или кода, в зависимости от обстоятельств).

    Хорошие модули обладают самодостаточными функциональными возможностями, поэтому они могут быть добавлены, перемещены или удалены по мере необходимости, не нарушив всю систему.

    Зачем вообще использовать модули?

    На самом деле у модулей есть много преимуществ. Наиболее важными, на мой взгляд, являются следующие:

  • Удобная поддержка (Maintainability): По определению, модуль является самодостаточным. Хорошо спроектированный модуль призван уменьшить зависимости частей вашей кодовой базы насколько это возможно, чтобы она могла расти и совершенствоваться не зависимо друг от друга. Обновить один модуль гораздо проще, когда он отделён от других частей кода.Возвращаясь к нашей книге, например, если вы захотите внести небольшое изменение в одну главу и это повлечёт за собой изменения какого-то другого раздела вашей книги, это будет кошмар. Поэтому главу нужно писать так, чтобы при внесении правок, не пришлось затрагивать другие главы.
  • Пространства имён (Namespacing): В JavaScript переменные которые находятся за пределами функций верхнего уровня считаются глобальными (каждый может получить к ним доступ). Поэтому очень распространено "Загрязнение пространства имён (namespace pollution)", где совершенно не связанный между собой код, связывают глобальные переменные.Совместное использование глобальных переменных в коде, который между собой не связан очень плохо в разработке .Дальше в этой статье мы увидим, что модули позволяют избежать загрязнения глобального пространства имён, путём создания приватных пространств для наших переменных.
  • Повторное использование (Reusability): Давайте будем честными. Все мы копировали код в новые проекты, который писали раньше. Например, давайте представим, что вы скопировали в новый проект некоторые вспомогательные методы из предыдущего проекта.Хорошо, но если вы найдете наиболее хороший способ написать эту часть, вам придётся вспомнить все места где фигурировал этот код чтобы обновить его.Это безусловно огромная трата времени. Намного проще было бы написать модуль и использовать его повторно снова и снова.
  • Как можно интегрировать модули?

    Есть много способов интегрировать модули в свои программы. Давайте рассмотрим некоторые из них:

    Паттерн "Модуль"

    Паттерн "Модуль" используется для имитации концепции классов (так как изначально JavaScript не поддерживал классы), поэтому мы можем хранить публичные и приватные методы (переменные) внутри одного объекта так, как делается это в классах других языков, таких как Java или Python. Это позволяет нам создать публичный API и предоставить возможность обращаться к публичным методам, в то время как приватные переменные и методы инкапсулированы в замыкании.

    Есть несколько способов реализации паттерна "Модуль". В первом примере я буду использовать анонимные замыкания. Помещение кода в анонимную функцию поможет нам достичь цели. (Помните, что в JavaScript функции - это единственный способ чтобы создать новую область видимости).

    Пример 1: Анонимные замыкания

    (function () { // We keep these variables private inside this closure scope var myGrades = ; var average = function() { var total = myGrades.reduce(function(accumulator, item) { return accumulator + item}, 0); return "Your average grade is " + total / myGrades.length + "."; } var failing = function(){ var failingGrades = myGrades.filter(function(item) { return item < 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); }());

    Таким образом, у нашей анонимной функции есть своя область видимости или "замыкание" и мы можем сразу её выполнить. Такой способ позволяет нам скрыть переменные из родительской (глобальной) области видимости.

    Что действительно хорошо в таком подходе, дак это то что вы можете использовать локальные переменные внутри этой функции и не бояться случайно перезаписать глобальные переменные с таким же именем. Но доступ к глобальным переменным у вас по прежнему остаётся, например так:

    Var global = "Hello, I am a global variable:)"; (function () { // We keep these variables private inside this closure scope var myGrades = ; var average = function() { var total = myGrades.reduce(function(accumulator, item) { return accumulator + item}, 0); return "Your average grade is " + total / myGrades.length + "."; } var failing = function(){ var failingGrades = myGrades.filter(function(item) { return item < 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); console.log(global); }()); // "You failed 2 times." // "Hello, I am a global variable:)"

    Пример 2: Глобальный импорт

    Другим популярным подходом, который используют библиотеки такие как jQuery, является глобальный импорт. Он похож на замыкания, которые мы только что видели, только теперь мы передаём глобальные переменные в качестве параметров.

    (function (globalVariable) { // Keep this variables private inside this closure scope var privateFunction = function() { console.log("Shhhh, this is private!"); } // Expose the below methods via the globalVariable interface while // hiding the implementation of the method within the // function() block globalVariable.each = function(collection, iterator) { if (Array.isArray(collection)) { for (var i = 0; i < collection.length; i++) { iterator(collection[i], i, collection); } } else { for (var key in collection) { iterator(collection, key, collection); } } }; globalVariable.filter = function(collection, test) { var filtered = ; globalVariable.each(collection, function(item) { if (test(item)) { filtered.push(item); } }); return filtered; }; globalVariable.map = function(collection, iterator) { var mapped = ; globalUtils.each(collection, function(value, key, collection) { mapped.push(iterator(value)); }); return mapped; }; globalVariable.reduce = function(collection, iterator, accumulator) { var startingValueMissing = accumulator === undefined; globalVariable.each(collection, function(item) { if(startingValueMissing) { accumulator = item; startingValueMissing = false; } else { accumulator = iterator(accumulator, item); } }); return accumulator; }; }(globalVariable));

    В этом примере GlobalVariable единственная глобальная переменная. Преимущество такого подхода в том, что все глобальные переменные вы объявляете заранее, что делает ваш код прозрачным для остальных.

    Пример 3: Объектный интерфейс

    Ещё один подход при создании модулей заключается в использовании автономных, объектных интерфейсов, например так:

    Var myGradesCalculate = (function () { // Keep this variable private inside this closure scope var myGrades = ; // Expose these functions via an interface while hiding // the implementation of the module within the function() block return { average: function() { var total = myGrades.reduce(function(accumulator, item) { return accumulator + item; }, 0); return"Your average grade is " + total / myGrades.length + "."; }, failing: function() { var failingGrades = myGrades.filter(function(item) { return item < 70; }); return "You failed " + failingGrades.length + " times."; } } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

    Как вы могли заметить, такой подход позволяет решать какие переменные (методы) мы хотим сделать приватными (например, myGrades ), а какие публичными поместив их в возвращаемый объект (например, average и failing ).

    Пример 4: Паттерн "Раскрывающийся модуль"

    Этот пример очень похож на предыдущий за исключением того, что все методы и переменные остаются приватными, пока их явно раскроют.

    Var myGradesCalculate = (function () { // Keep this variable private inside this closure scope var myGrades = ; var average = function() { var total = myGrades.reduce(function(accumulator, item) { return accumulator + item; }, 0); return"Your average grade is " + total / myGrades.length + "."; }; var failing = function() { var failingGrades = myGrades.filter(function(item) { return item < 70; }); return "You failed " + failingGrades.length + " times."; }; // Explicitly reveal public pointers to the private functions // that we want to reveal publicly return { average: average, failing: failing } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

    Это может показаться большим объёмом информации, но это только верхушка айсберга, когда дело доходит до паттернов модулей. Вот некоторые полезные ресурсы, которые нашёл проводя свои исследования:

    • от Addy Osmani: это клад с деталями и выразительно кратким содержанием;
    • Adequately Good by Ben Cherry : полезный обзор с примерам расширенного использования паттерна "Модуль";
    • Blog of Carl Danley : обзор паттерна "Модуль" и ресурсы для других JavaScript паттернов;
    CommonJS и AMD

    У всех перечисленных выше подходов есть одно общее свойство: они все создают одну глобальную переменную, в которую помещают код функции, создавая тем самым приватное пространство имён и используют область видимости замыкания.

    Хоть каждый из этих подходов и эффективен по своему, у них есть и свои недостатки.

    Вы как разработчик должны знать правильный порядок загрузки файлов. Например, предположим, что вы используете Backbone в своём проекте, поэтому вы подключаете скрипт Backbone"а через тег в своём файле. Так как Backbone напрямую зависит от Underscore.js, вы не можете подключить скрипт Backbone.js перед Underscore.js.

    Управление зависимостями для разработчика иногда доставляет головную боль.

    Другой недостаток заключается в том, что всё ещё может произойти конфликт пространств имён. Например, у вас может быть два модуля с одинаковыми именами или две версии одного модуля и они обе вам нужны.

    Исходя из этого возникает интересный вопрос: можем ли мы обращаться к интерфейсу модуля не через глобальную область видимости?

    К счастью, ответ да.

    Есть два популярных и хорошо реализованных подхода: CommonJS и AMD. CommonJS

    CommonJS - это добровольная группа разработчиков, которая проектируют и реализует JavaScript API для объявления модулей.

    Модуль CommonJS - это фрагмент JavaScript кода предназначенный для многократного использования. Он экспортирует специальные объекты, делая их доступными для других модулей, чтобы они могли включать их в свои зависимости. Если вы программировали на Node.js, то вам это будет очень хорошо знакомо.

    С CommonJS в каждом JavaScript файле модуль хранится в своём собственном уникальном контексте (так же, как и в замыканиях). В этом пространстве мы используем объект module.exports чтобы экспортировать модули, и require чтобы подключить их.

    Определение CommonJS модуля может выглядеть следующим образом:

    Function myModule() { this.hello = function() { return "hello!"; } this.goodbye = function() { return "goodbye!"; } } module.exports = myModule;

    Мы используем специальный объект module и размещаем ссылку на нашу функцию в module.exports . За счёт этого CommonJS знает, что мы хотим открыть модуль так, чтобы другие файлы могли его использовать.

    После этого, когда кто-то захочет использовать наш myModule , он без проблем сможет его подключить следующим образом:

    Var myModule = require("myModule"); var myModuleInstance = new myModule(); myModuleInstance.hello(); // "hello!" myModuleInstance.goodbye(); // "goodbye!"

    У данного подхода есть два очевидных преимущества над подходами, которые мы обсуждали раньше:

  • Отсутствие загрязнения глобального пространства имён;
  • Становление наших зависимостей более явными;
  • Кроме того, очень компактный синтаксис, я это очень люблю.

    Нужно отметить, что CommonJS использует server-first подход и модули загружаются синхронно. Это важно потому что если у нас есть ещё три модуля, которые нам нужно подключить, он будет загружать их один за другим.

    Сейчас это прекрасно работает на сервере, но к сожалению, это затрудняет написание браузерного JavaScript. На получение модуля из интернета уходит намного больше времени, чем на получение модуля с жёсткого диска. Пока скрипт загружает модуль, браузер блокируется и вы ничего не можете сделать, до тех пор, пока он не закончит загрузку. Он ведёт себя так потому что JavaScript поток останавливается, пока загружается код (Я расскажу вам как мы может обойти эту проблему во второй части статьи, когда мы будем рассматривать сборку модулей. На данный момент это всё, что нам нужно знать).

    AMD

    CommonJS хорош, но что если нам нужно загружать модули асинхронно? Ответ на этот вопрос "Асинхронное определение модулей (Asynchronous Module Definition)" или просто AMD.

    Define(["myModule", "myOtherModule"], function(myModule, myOtherModule) { console.log(myModule.hello()); });

    Функция определения модуля принимает первым аргументом массив зависимостей. Эти зависимости загружаются в фоновом (не блокирующим) режиме и вызывают функцию обратного вызова, которая была передана вторым аргументом.

    Далее, функция обратного вызова в качестве аргументов принимает уже загруженные зависимости, и позволяет использовать их. И наконец сами зависимости тоже должны быть определены с помощью ключевого слова define .

    Например, myModule может выглядеть следующим образом:

    Define(, function() { return { hello: function() { console.log("hello"); }, goodbye: function() { console.log("goodbye"); } }; });

    Итак, давайте пройдёмся ещё раз. В отличии от CommonJS, AMD реализует browser-first подход вместе с асинхронным поведением (Обратите внимание, что достаточно много людей утверждают, что динамическая загрузка файлов не благоприятна при выполнении вашего кода. Об этом мы поговорим больше в следующей части нашей статьи, посвящённой сборке модулей).

    Кроме асинхронности, у AMD есть ещё одно преимущество. AMD модули могут быть функциями, конструкторами, строками, JSON"ом и другими типами, в то время как CommonJS в качестве модулей поддерживает только объекты.

    Из минусов, AMD не совместим с io, файловой системой и другими серверно-ориентированными особенностями, которые доступны через CommonJS. И синтаксис функции объявления модулей многословен в сравнении с просты require .

    UMD

    Для проектов, которые требуют поддержки функций обеих систем AMD и CommonJS, есть ещё один формат. Универсальное Объявление Модулей (Universal Module Definition), ну или по простому UMD.

    По существу, UMD предоставляет возможность использование любого из двух вышеперечисленных способов, плюс поддерживает определение модулей через глобальную переменную. В результате, модули UMD могут работать как на клиенте, так и на сервере.

    Быстрый пример того, как работает UMD:

    (function (root, factory) { if (typeof define === "function" && define.amd) { // AMD define(["myModule", "myOtherModule"], factory); } else if (typeof exports === "object") { // CommonJS module.exports = factory(require("myModule"), require("myOtherModule")); } else { // Browser globals (Note: root is window) root.returnExports = factory(root.myModule, root.myOtherModule); } }(this, function (myModule, myOtherModule) { // Methods function notHelloOrGoodbye(){}; // A private method function hello(){}; // A public method because it"s returned (see below) function goodbye(){}; // A public method because it"s returned (see below) // Exposed public methods return { hello: hello, goodbye: goodbye } }));

    Нативный JS

    Фууух. Вы ещё рядом? Я не потерял вас в этом лесу? Хорошо! Потому что у нас есть ещё один тип определения модулей.

    Как вы могли заметить выше, ни один из модулей не был родным для JavaScript. Вместо этого мы имитировали систему модулей, используя либо паттерн "Модуль", либо CommonJS, либо AMD.

    К счастью умные люди из TC39 (the standards body that defines the syntax and semantics of ECMAScript) добавили встроенные модули в ECMAScript 6 (ES6).

    ES6 предлагает разнообразные возможности для импорта и экспорта модулей, про которые рассказывали не один раз. Вот парочка ресурсов:

    • jsmodules.io
    • exploringjs.com

    Что хорошего в ES6 модулях в сравнении с CommonJS и AMD? То, что он собрал лучшее из двух миров: компактность, декларативный синтаксис, асинхронную загрузку, плюс дополнительные преимущества, такие как циклические зависимости.

    Вероятно, моя любимая особенность ES6 модулей заключается в том, что импорты это живые read-only виды экспортов (в сравнении с CommonJS, где импорт это просто копия экспорта).

    Вот пример того, как это работает:

    // lib/counter.js var counter = 1; function increment() { counter++; } function decrement() { counter--; } module.exports = { counter: counter, increment: increment, decrement: decrement }; // src/main.js var counter = require("../../lib/counter"); counter.increment(); console.log(counter.counter); // 1

    В этом примере мы сделали две копии базового модуля: первый раз когда экспортировали его, а второй раз когда импортировали.

    Кроме того, копия которая находится в main.js теперь отключена от оригинального модуля. Поэтому, даже когда мы увеличиваем наш счётчик, он всё равно возвращает 1, так как counter - это переменная которую мы импортировали из модуля, отключённая от оригинального модуля.

    Таким образом, увеличение счётчика будет увеличивать его в модуле, но не будет увеличивать в скопированной версии. Единственный способ изменить скопированную версию, это увеличить её вручную:

    Counter.counter++; console.log(counter.counter); // 2

    А, ES6 при импорте создает живой read-only вид модуля:

    // lib/counter.js export let counter = 1; export function increment() { counter++; } export function decrement() { counter--; } // src/main.js import * as counter from "../../counter"; console.log(counter.counter); // 1 counter.increment(); console.log(counter.counter); // 2

    Интересно, не правда ли? Что я нахожу действительно убедительным в живых read-only видах, дак это то, что они позволяют разделить ваши модули на более мелкие куски без потери функциональности.

    Вы можете развернуть и объединить их заново (в новом проекте), и никаких проблем. Всё будет работать.

    Немного заглядывая вперёд: Сборка модулей

    Вау! Как быстро пролетело время. Это было крутое путешествие и я искренне надеюсь, что статья дала вам возможность лучше понять модули в JavaScript.

    В следующей статье мы рассмотрим связывание модулей, затронем основные темы, включая:

    • Почему мы собираем модули;
    • Различные подходы к сборке;
    • API загрузчика модулей ECMAScript;
    • И ещё много всего...

    Математические операции являются одними из самых базовых и универсальных функций любого языка программирования. В JavaScript числа часто используются в общих задачах, таких как определение размеров окна браузера, вычисление окончательной цены денежной транзакции или расстояния между элементами в документе сайта.

    Чтобы быть хорошим разработчиком, иметь высокие навыки в математике не обязательно, однако для этого важно знать, какие типы операций доступны в JavaScript и как использовать их для выполнения практических задач.

    В отличие от других языков программирования, JavaScript имеет только один числовой тип данных; он не разделяет целые числа и числа с плавающей точкой.

    Это руководство расскажет об арифметических операторах, операторах присваивания и порядке операций с числовыми данными JavaScript.

    Арифметические операторы

    Арифметические операторы – это символы, которые определяют математические операции и возвращают результат. К примеру, в 3 + 7 = 10 символ + определяет синтаксис операции сложения.

    Многие операторы JavaScript знакомы вам из базовой математики, но есть также и несколько дополнительных операторов.

    Все арифметические операторы JavaScript представлены в следующей таблице.

    Оператор Синтаксис Пример Определение
    Сложение + x + y Сумма x и y
    Вычитание x — y Разница между x и y
    Умножение * x * y Производное x и y
    Деление / x / y Частное x и y
    Модуль % x % y Остаток x / y
    Возведение в степень ** x ** y x в степени y
    Инкремент ++ x++ x плюс один
    Декремент x— x минус один
    Сложение и вычитание

    Операторы сложения и вычитания доступны в JavaScript и могут использоваться для нахождения суммы и разности числовых значений. JavaScript имеет встроенный калькулятор, а математические операции могут выполняться непосредственно в консоли.

    Знак плюса позволяет складывать числа, например:

    Помимо операций с простыми числами JavaScript позволяет присваивать числа переменным и выполнять с ними вычисления. Для примера можно присвоить числовые значения переменным x и y, а результат поместить в z.

    // Assign values to x and y
    let x = 10;
    let y = 20;
    // Add x and y and assign the sum to z
    let z = x + y;
    console.log(z);
    30

    // Assign values to x and y
    let x = 10;
    let y = 20;
    // Subtract x from y and assign the difference to z
    let z = y - x;
    console.log(z);
    10

    // Assign values to x and y
    let x = -5.2;
    let y = 2.5;
    // Subtract y from x and assign the difference to z
    let z = x - y;
    console.log(z);
    -7.7

    В JavaScript есть одна интересная особенность, которую следует учитывать и знать, — это результат сложения числа и строки. Мы знаем, что 1 + 1 должно равняться 2, но это уравнение выдаст неожиданный результат.

    let x = 1 + "1";
    console.log(x);
    typeof x;
    11
    "string"

    Вместо сложения чисел JavaScript преобразует все выражение в строки и объединяет их. Важно быть осторожным с динамической типизацией JavaScript, поскольку она может иметь нежелательные результаты.

    Сложение и вычитание в JavaScript часто используются для прокрутки панели навигации.

    function scrollToId() {
    const navHeight = 60;
    window.scrollTo(0, window.pageYOffset - navHeight);
    }
    window.addEventListener("hashchange", scrollToId);

    В этом случае панель будет прокручиваться на 60 пикселей от id.

    Умножение и деление

    Операторы умножения и деления JavaScript используются для поиска производного и частного числовых значений.

    Звездочка является оператором умножения.

    // Assign values to x and y
    let x = 20;
    let y = 5;
    // Multiply x by y to get the product
    let z = x * y;
    console.log(z);
    100

    Умножение можно использовать для расчета цены товара после введения налога с продаж.

    const price = 26.5; // Price of item before tax
    const taxRate = 0.082; // 8.2% tax rate
    // Calculate total after tax to two decimal places
    let totalPrice = price + (price * taxRate);
    totalPrice.toFixed(2);
    console.log("Total:", totalPrice);
    Total: 28.67

    Слеш – оператор деления.

    // Assign values to x and y
    let x = 20;
    let y = 5;
    // Divide y into x to get the quotient
    let z = x / y;
    console.log(z);
    4

    Деление особенно полезно при расчете времени, например, при вычислении количества часов или процента правильных ответов в тесте.

    Модуль числа

    Модуль – еще один арифметический оператор, менее популярный, чем предыдущие. Представлен символом %. Он возвращает остаток при делении первого числа на второе.

    К примеру, мы знаем, что 9 делится на 3 без остатка:

    Модуль числа позволяет определить четное или нечетное число, например:

    // Initialize function to test if a number is even
    const isEven = x => {
    // If the remainder after dividing by two is 0, return true
    if (x % 2 === 0) {
    return true;
    }
    // If the number is odd, return false
    return false;
    }
    // Test the number
    isEven(12);
    true

    В этом примере 12 делится на 2, следовательно, это четное число.

    В программировании модуль числа часто используется в сочетании с условными операторами.

    Возведение в степень

    Возведение в степень – один из самых новых операторов JavaScript. Синтаксис возведения в степень – две звездочки подряд (**).

    К примеру, 10 в пятой степени (10^5) записывается так:

    10 ** 5;
    100000

    Операция 10 ** 5 имеет тот же результат, что 10 * 10, повторенная 5 раз.

    10 * 10 * 10 * 10 * 10;

    Также эту операцию можно записать с помощью метода Math.pow().

    Math.pow(10, 5);
    100000

    Использование оператора возведения в степень – быстрый способ определить степень заданного числа, но, как обычно, при выборе между методом и оператором важно быть последовательными и писать код в одном стиле.

    Инкремент и декремент

    Операторы инкремента и декремента увеличивают или уменьшают числовое значение переменной на единицу. Они представлены двумя плюсами (++) или двумя минусами (—) и часто используются в циклах.

    Обратите внимание: операторы инкремента и декремента могут использоваться только с переменными. Попытка использовать их с простыми числами приведет к ошибке.

    7++
    Uncaught ReferenceError: Invalid left-hand side expression in postfix operation

    Операторы инкремента и декремента можно классифицировать как префиксные и постфиксные операции, в зависимости от того, где по отношению к переменной размещен оператор.

    Префиксный инкремент записывается как ++х.

    // Set a variable
    let x = 7;

    let prefix = ++x;
    console.log(prefix);
    8

    Значение х увеличилось на 1. Постфиксный инкремент пишется как у++.

    // Set a variable
    let y = 7;
    // Use the prefix increment operation
    let postfix = y++;
    console.log(postfix);
    7

    Постфиксная операция не увеличила значение. Это значение не будет увеличиваться до тех пор, пока выражение не будет оценено. Для этого нужно запустить операцию дважды:

    let y = 7;
    y++;
    y++;
    console.log(y);
    8

    Чаще всего эти операторы встречаются в циклах. В данном цикле for оператор запускается 10 раз, начиная с 0.

    // Run a loop ten times
    for (let i = 0; i < 10; i++) {
    console.log(i);
    }
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

    В этом примере итерация цикла выполняется с помощью оператора инкремента.

    Проще говоря, х++ можно воспринимать как сокращение от х = х + 1, а х-как сокращение от х = х – 1.

    Операторы присваивания

    Одним из наиболее часто используемых операторов является оператор присваивания, который уже встречался в этом мануале. Он представлен знаком равенства (=). Символ = используется для присвоения значения справа переменной слева.

    // Assign 27 to age variable
    let age = 27;

    Помимо стандартного оператора присваивания JavaScript имеет составные операторы присваивания, которые комбинируют арифметический оператор с оператором =.

    К примеру, оператор добавления начнет с исходного значения и добавит к нему новое значение.

    // Assign 27 to age variable
    let age = 27;
    age += 3;
    console.log(age);
    30

    По сути, age += 3 – то же самое, что и age = age + 3.

    Все арифметические операторы можно объединять с оператором присваивания. Ниже приведена справочная таблица операторов присваивания в JavaScript.

    Составные операторы присваивания часто используются в циклах, как инкременты и декременты.

    Приоритет операторов

    Операторы выполняются в порядке приоритетности, как и в обычной математике.

    К примеру, умножение имеет более высокий приоритет, чем сложение.

    // First multiply 3 by 5, then add 10
    10 + 3 * 5;
    25

    Если сначала нужно выполнить операцию сложения, возьмите ее в круглые скобки – такие операции всегда имеют наивысший приоритет.

    // First add 10 and 3, then multiply by 5
    (10 + 3) * 5;
    65

    Ниже вы найдете таблицу приоритета арифметических операторов в JavaScript. Для инкремента и декремента постфикс имеет более высокий приоритет, чем префикс.

    Инкремент/декремент, умножение/деление и сложение/вычитание имеют одинаковый уровень приоритета.

    Приоритет имеют не только арифметические операторы, но и операторы присваивания, логические операторы, условные операторы и т. д. Полный список можно посмотреть .

    Tags:
    просмотров