Как мне обойти восьмеричное поведение parseInt в JavaScript? - PullRequest
276 голосов
/ 12 мая 2009

Попробуйте выполнить следующее в JavaScript:

parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!

Я только что понял, как JavaScript считает, что начальный ноль указывает восьмеричное целое число , и поскольку в base-8 нет "8" или "9", функция возвращает ноль. Как ни крути, это по замыслу .

Какие обходные пути?

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


Обновление:

В 5-м издании стандарта JavaScript ( ECMA-262 ) вводятся серьезные изменения, устраняющие это поведение. У Mozilla хорошая рецензия .

Ответы [ 9 ]

321 голосов
/ 12 мая 2009

Это распространенная ошибка в Javascript с простым решением:

Просто укажите основание , или 'radix', вот так:

parseInt('08',10); // 8

Вы также можете использовать Число :

Number('08'); // 8
42 голосов
/ 05 января 2010

Если вы знаете, , что ваше значение будет находиться в 32-разрядном целочисленном диапазоне со знаком, тогда ~~x будет действовать правильно во всех сценариях.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

Если вы ищите двоичный файл не (~), спецификация требует преобразования "ToInt32" для аргумента, который выполняет очевидное преобразование в Int32 и определено для приведения NaN значений к нулю.

Да, это невероятно хакерски, но так удобно ...

24 голосов
/ 12 мая 2009

Из документации parseInt используйте необязательный аргумент radix, чтобы указать base-10:

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

Это кажется мне педантичным, запутанным и многословным (действительно, дополнительный аргумент в каждом отдельном parseInt?), Поэтому я надеюсь, что есть лучший путь.

11 голосов
/ 12 мая 2009
function parseDecimal(s) { return parseInt(s, 10); }

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

10 голосов
/ 12 мая 2009

Укажите базу:

var number = parseInt(s, 10);
7 голосов
/ 12 мая 2009

Было бы очень непослушно заменить parseInt версией, которая предполагает десятичность, если у нее нет второго параметра? (примечание - не проверено)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}
5 голосов
/ 18 июля 2015

Вы также можете вместо использования parseFloat или parseInt использовать унарный оператор ( + ).

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

и для хорошей меры

+"09.09"
// => 9.09

MDN Link

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

5 голосов
/ 20 января 2012

Как насчет десятичного числа:

('09'-0) === 9  // true

('009'-0) === 9 // true
4 голосов
/ 17 июля 2011

Если вы уже выполнили кучу кодирования с помощью parseInt и не хотите добавлять «10» ко всему, вы можете просто переопределить функцию, чтобы сделать base 10 по умолчанию:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

Это может сбить с толку более позднего читателя, поэтому создание функции parseInt10 () может быть более понятным. Лично я предпочитаю использовать простую функцию, чем постоянно добавлять «10» - просто создает больше возможностей для ошибок.

...