Что такое символ десятичного разделителя в JavaScript? - PullRequest
43 голосов
/ 18 января 2010

Меня поразила мысль, когда я писал фрагмент кода JavaScript, который обрабатывал некоторые значения с плавающей запятой. Что такое символ десятичной точки в JavaScript? Это всегда .? Или это зависит от культуры? А что насчет .toFixed() и .parseFloat()? Если я обрабатываю пользовательский ввод, он, скорее всего, будет включать символ десятичного разделителя для конкретной культуры.

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

Добавлено: ОК, Рубенс Фариас предлагает посмотреть на аналогичный вопрос , на который есть аккуратно принятый ответ:

function whatDecimalSeparator() {
    var n = 1.1;
    n = n.toLocaleString().substring(1, 2);
   return n;
}

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

Теперь оставшаяся часть будет определять поведение .parseFloat(). В нескольких ответах указывается, что для литералов с плавающей запятой допустимо только .. .parseFloat() действует так же? Или может потребоваться локальный десятичный разделитель в каком-то браузере? Существуют ли другие методы для разбора чисел с плавающей точкой? Должен ли я выкатить свой собственный, чтобы быть уверенным?

Ответы [ 3 ]

21 голосов
/ 18 января 2010

В соответствии со спецификацией, DecimalLiteral определяется как:

DecimalLiteral ::
    DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt 
    . DecimalDigits ExponentPartopt 
    DecimalIntegerLiteral ExponentPartopt

и для удовлетворения аргумента parseFloat:

  1. Пусть inputString будет ToString (string).
  2. Пусть trimmedString будет подстрокой inputString, состоящей из крайнего левого символа, который не является StrWhiteSpaceChar, и всех символов справа от этого символа (другими словами, удалите начальный пробел.)
  3. Если ни trimmedString, ни какой-либо префикс trimmedString не удовлетворяют синтаксису StrDecimalLiteral (см. 9.3.1), верните NaN.
  4. Пусть numberString будет самым длинным префиксом trimmedString, который может быть сам TrimmString, который удовлетворяет синтаксису StrDecimalLiteral.
  5. Возвращает числовое значение для MV

Таким образом, numberString становится самым длинным префиксом trimmedString, который удовлетворяет синтаксису StrDecimalLiteral, то есть первым разбираемым литеральным номером строки, который он находит во входных данных. Только . может использоваться для указания числа с плавающей запятой. Если вы принимаете входные данные из разных локалей, используйте строку replace:

function parseLocalNum(num) {
    return +(num.replace(",", "."));
}

Функция использует унарный оператор вместо parseFloat, потому что мне кажется, что вы хотите быть строгими в отношении ввода. parseFloat("1ABC") будет 1, тогда как при использовании унарного оператора +"1ABC" возвращает NaN. Это намного облегчает проверку ввода. Использование parseFloat просто предполагает, что ввод имеет правильный формат.

12 голосов
/ 18 января 2010

использование:

theNumber.toLocaleString();

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

2 голосов
/ 18 января 2010

Насколько я знаю, сам javascript знает только о разделителе . для десятичных дробей. По крайней мере, один человек, чье мнение я доверяю в отношении вещей JS, согласен:

http://www.merlyn.demon.co.uk/js-maths.htm#DTS

...