Для преобразования строки в число в JavaScript используются два метода: parseInt - для целых чисел и parseFloat для чисел с плавающей запятой. В официальной документации про parseInt сказано примерно следующее:
Метод parseInt возвращает целое значение, равное числу, содержащемуся в его параметре. Если параметр не может быть обработан как целое, возвращается NaN.
И почти то же самое про parseFloat:
Метод parseFloat возвращает числовое значение, содержащееся в его параметре. Если параметр не может быть обработан как число с плавающей точкой, возвращается значение NaN.
Вроде бы все логично и понятно. Еще небольшое отличие, что parseInt имеет второй параметр - основание системы счисления, в которой рассматривается конвертируемое число, к нему мы вернемся чуть позже. А теперь от красивой теории перейдем к суровой практике.
Тепличные условия рассматривать не будем, сразу возьмем какую-нибудь корявую тестовую строку, например, "1234.56fuck":
var a = "1234.56fuck";
alert (parseInt(a));
alert (parseFloat(a));
Первый раз получаем сообщение
1234, второй раз
1234.56. Я, конечно, могу ошибаться, но по моему разумению строка из этого примера числом не является. Вообще не является. PHP, к примеру, при попытке превратить такую строку в число, однозначно вернет ноль или false. Не знаю, чем руководствовались разработчики JavaScript, но обе функции обрабатывают строку до первого символа, который они не могут распознать в качестве цифры, пробела или разделителя десятичной дроби, и такое поведение также описано в документации. Значение NaN возвращается только в случае, если первый же символ строки не является пробелом или цифрой. Чем это может грозить? Ситуация: на клиентской стороне средствами JavaScript выполняются некоторые проверки или вычисления, основанные на данных, введенных вручную пользователем. Полученные расчетные и введенные данные передаются на сервер и там обрабатываются серверными языками. При ошибке или намеренном искажении ввода могут получиться разногласия с ожидаемыми результатами. Лично я считаю, что любое не-число должно обрабатываться именно как не-число, без вариантов. Для приведения строки к числовому виду я использую такой нехитрый трюк:
var a = '12345.67';
alert (a-0);
var a = '12345.67fuck';
alert (a-0);
В первом случае мы получим ожидаемое
12345.67, а во втором -
NaN, как и должно быть. Вместо вычитания нуля можно умножать на 1, результат будет тот же самый. Почему нельзя прибавлять ноль? Потому что он будет просто дописан как символ '0' в конец строки. Более универсальная функция для преобразования строки в число будет выглядеть так:
function StrToNum(a) {
return (a-0);
}
Плюсы этого способа: работает как с целыми, так и с дробными числами, точно определяет не-числа. Возможный минус: обрабатываются только десятичные и шестнадцатеричные числа, другие системы счисления не поддерживаются.
Переходим ко второй части Марлезонского балета. Попробуйте выполнить следующий пример сперва в уме, а затем в браузере:
var a = '00012';
var b = '00008';
alert (parseInt(a) + parseInt(b));
Ожидаете, что в сумме получится 20? Однако это не так. Результат этого сложения будет 10. Давайте разберемся, почему так происходит. Если не указана система счисления для конвертирования (второй параметр вызова - radix), то принимаются следующие умолчания: если строка начинается с "0х", то radix = 16; если строка начинается с "0", то radix = 8; в остальных случаях radix = 10. Из-за этого строка '00012' подразумевается записанной в восьмеричной системе счисления и преобразуется в десятичное 10, а строка '00008' преобразуется в 0, потому что цифры 8 в восьмеричной системе счисления вообще нет. Чтобы избежать подобной путаницы, надо всегда явно указывать основание системы счисления в вызове parseInt, но краткий экскурс по
Google Code наглядно показывает, что это делается далеко не всеми разработчиками. Альтернативное решение - пользоваться указанной выше функцией StrToNum:
var a = '00012';
var b = '00008';
alert (StrToNum(a) + StrToNum(b));
Вот теперь в результате получаем 20. Метод с вычитанием кроссбраузерный, работает надежно и без ошибок. Так что свой выбор я уже сделал.