Теперь, когда мы
с вами подробно познакомились с функциями, объектами и методами вернемся к
примитивным типам данных и посмотрим, какими полезными методами они обладают. Да,
все верно, JavaScript так устроен,
что примитивные типы тоже имеют свои методы подобно объектам. И начнем
рассмотрение с числового типа Number.
Форматы записи чисел
Ранее мы уже
говорили, что в JavaScript числа можно задавать следующим образом:
let a1 = 1e9; // 1 000 000 000
let a2 = 0.5e3; // 0.5*1000 = 500
let a3 = 1e-6; // 0.000001
let a4 = 0xff; // шестнадцатиричная запись (ff = 255)
let a5 = 0b11111111; // двоичная запись десятичного числа 255
let a6 = 0o377; // восьмеричная форма записи числа 255
Можно
использовать и другие системы счисления, но они почти не встречаются на
практике.
Особенности числовой арифметики
В JavaScript
число представлено в виде 64-битного формата IEEE-754. Для хранения числа
используется 64 бита: 52 из них используется для хранения цифр, 11 из них для
хранения положения десятичной точки (если число целое, то хранится 0), и один
бит отведён на хранение знака. Если число слишком большое, оно переполнит
64-битное хранилище, JavaScript вернёт бесконечность:
console.log( 1e500 ); // Infinity
Наиболее часто
встречающаяся ошибка при работе с числами в JavaScript – это потеря точности.
Например, сумма двух таких вещественных чисел:
let res = 0.1+0.2;
console.log( res );
не дает точное
значение 0,3. Потому, например, при таком сравнении:
if(res == 0.3) console.log( true );
мы получим
значение false и оператор
после if выполнен не
будет. Почему так происходит? Не вдаваясь в подробности, можно сказать так:
вещественные числа 0.1 и 0.3 в двоичной системе счисления (именно так они
представляются в памяти ЭВМ) являются бесконечной дробью. Отсюда и потеря
точности.
Как обойти эту
проблему и корректно работать с такими числами? Если это имеет значение, то в
общем случае нужно придумывать свои подходы в каждой конкретной ситуации.
Например, если разрабатывается интернет-магазин, то все вычисления можно делать
целыми числами, выраженные в копейках и только на экране браузера результат
отображать в рублях и копейках. И так далее. Здесь каждый сам решает как ему
обойти эту проблему.
toString(base)
Метод
num.toString(base) возвращает строковое представление числа num в системе
счисления base. Например:
let num = 255;
console.log( num.toString(16) ); // ff
console.log( num.toString(2) ); // 11111111
Параметр base может принимать
целые значения из диапазона от 2 до 36 (по умолчанию 10). Интересной
особенностью записью методов у чисел служит такой синтаксис:
let res = 127..toString(16);
console.log( res );
После любого
числа можно поставить две точки и вызвать любой числовой метод.
Методы округления чисел
В JavaScript имеется
встроенный объект Math, предоставляющий различные математические методы.
Здесь мы рассмотрим функции, связанные с округлением чисел. Они следующие:
-
Math.floor – округление в
меньшую сторону;
-
Math.ceil – округление в
большую сторону;
-
Math.round – округление до
ближайшего целого.
Например:
let dig = 1.5;
let res = Math.floor(dig);
console.log( res ); // 1
console.log( Math.ceil(dig) ); // 2
console.log( Math.round(1.4) ); // 1
console.log( Math.round(1.5) ); // 2
А что если мы
хотим округлить число до второго знака после запятой (до сотых)? Это можно
сделать, например, так:
let dig = 1.23456;
let res = Math.round(dig*100)/100;
console.log( res );
Но для такой
операции в JavaScript имеется
встроенный числовой метод toFixed(n), где n – число знаков
после запятой. Наш пример можно переписать так:
console.log( dig.toFixed(2) );
isFinite и isNaN
Если по каким-то
причинам результатом вычислений становятся значения Infinite или NaN, то было бы
полезно иметь функции, которые бы умели «узнавать» такие выражения. Этими
функциями как раз и являются isFinite и isNaN. Например:
console.log( isNaN(NaN) ); // true
console.log( isNaN("1") ); // false
console.log( isNaN(2) ); // false
console.log( isNaN("abc") ); // true
По аналогии
работает и вторая функция isFinit:
console.log( isFinite("15") ); // true
console.log( isFinite("str") ); // false, потому что специальное значение: NaN
console.log( isFinite(Infinity) ); // false
Как видим, она
возвращает true, если это число
и оно ограничено (не бесконечно) и false в других
случаях.
Кстати, иногда
isFinite используется для проверки: содержится ли в строке число:
let num = prompt("Enter a number", '');
if( isFinite(num) ) console.log("это число");
else console.log("это не число");
Правда, если num будет пустой
строкой, то эта функция решит, что это число 0 (так как пустая строка
приводится к числу 0). Поэтому, более точная проверка будет такой:
if( num.length > 0 && isFinite(num) ) console.log("это число");
else console.log("это не число");
parseInt и parseFloat
Данные методы
позволяют выделить число из строки, даже если в строке имеются другие не
числовые символы. Например, при работе с CSS часто
встречаются такие выражения: «12pt», «100%», «340px» и прочее. Если
мы попытаемся получить значения с помощью уже знакомых нам подходов:
let arg1 = "12pt";
let arg2 = "100%";
let arg3 = "340px";
console.log( Number(arg1) );
console.log( +arg2 );
console.log( +arg3 );
То всюду получим
значение NaN. Но, функии parseInt и parseFloat справляются с
такими задачами. Они преобразовывают строку в число до тех пор, пока либо не
дойдут до конца, либо не встретится ошибка преобразования. В данном случае,
получим всюду правильные числовые значения:
console.log( parseInt(arg1) );
console.log( parseInt(arg2) );
console.log( parseInt(arg3) );
Если же в строке
предполагается вещественное число, то применяется вторая функция:
console.log( parseFloat("12.5pt") );
console.log( parseFloat(" 90.5% ") );
console.log( parseFloat("+30.5px") );
Функция parseInt имеет второй
необязательный аргумент, в котором можно указать систему, в которой
представлено число, например:
console.log( parseInt('0xff', 16) ); // 255
console.log( parseInt('aa', 16) ); // 170, можно и без 0x
console.log( parseInt('11011', 2) ); // 27
Другие математические функции
Math.random() возвращает
псевдослучайное число в диапазоне (0; 1], например:
for(let i = 0;i < 10;++i)
console.log( Math.random() );
Причем, при
каждом запуске будем получать разные последовательности чисел.
Math.max(a, b, c...) / Math.min(a, b, c...) возвращают наибольшее/наименьшее число из переданных аргументов:
let max = Math.max(1, 2, 0, -10, 5, 7);
let min = Math.min(1, 2, -10, 5);
console.log( max ); // 7
console.log( min ); // -10
Число аргументов
может быть любым.
Math.pow(n, power) возвращает число n, возведённое в степень power:
console.log( Math.pow(2, 10) ); // 2 в степени 10 = 1024
Объект Math содержит
множество других функций (cos, sin) и констант,
например, PI, которыми удобно
оперировать в JavaScript.