Как обойти восьмеричное поведение parseInt в JavaScript?

StackOverflow https://stackoverflow.com/questions/850341

  •  21-08-2019
  •  | 
  •  

Вопрос

Попробуйте выполнить следующее в 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 считает, что ведущий ноль указывает на восьмеричное целое число, и поскольку нет "8" или "9" в системе счисления с основанием 8 функция возвращает ноль.Нравится или нет, это задумано.

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

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


Обновлять:

Пятое издание стандарта JavaScript (ЭКМА-262) вносит критическое изменение, которое устраняет такое поведение.У Мозиллы есть хорошая записать.

Это было полезно?

Решение

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

Только укажите базу, или «основание», например:

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

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

Number('08'); // 8

Другие советы

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

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

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

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

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

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

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

function parseDecimal(s) { return parseInt(s, 10); }

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

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

var number = parseInt(s, 10);

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

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

Как насчет этого для десятичной дроби:

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

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

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

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

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

+"09.09"
// => 9.09

МДН-ссылка

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top