JavaScript中的十进制分隔符号是什么?

51
当我在编写一些处理浮点数值的JavaScript代码时,我突然想到一个问题:JavaScript中的小数点符号是什么?它总是.吗?还是与文化相关?那么.toFixed().parseFloat()呢?如果我正在处理用户输入,那么很可能包括本地特定于文化的小数分隔符号。
最终,我希望编写支持用户输入中的两个小数点(特定于文化和.)的代码,但如果不知道JavaScript需要什么,就无法编写这样的代码。 添加:好的,Rubens Farias 建议 查看类似的问题,其中有一个不错的被接受的答案:
function whatDecimalSeparator() {
    var n = 1.1;
    n = n.toLocaleString().substring(1, 2);
   return n;
}

很好,这让我得到了本地小数点。毫无疑问,这是解决方案的一步。
现在,剩下的部分将是确定.parseFloat()的行为。几个答案指出,对于浮点字面量,仅.是有效的。 .parseFloat()是否表现相同?或者某些浏览器需要本地小数分隔符?还有其他不同的解析浮点数的方法吗?我应该自己编写以确保吗?

@Vilx- 对于你的操作,我建议使用一元(+)运算符而不是parseFloat()。 这样在验证输入时会更容易。请参考我的更新答案。 - Andy E
3个回答

24

根据规范,DecimalLiteral被定义为:

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

为了满足 parseFloat 的参数:

  1. 将 string 转换为字符串 inputString。
  2. 将 trimmedString 定义为 inputString 的子字符串,包括不是 StrWhiteSpaceChar(空格)的最左边字符和该字符右侧的所有字符。(换句话说,删除前导空白)
  3. 如果 trimmedString 或其任何前缀都不符合 StrDecimalLiteral(参见 9.3.1) 的语法,则返回 NaN。
  4. 将 numberString 定义为 trimmedString 的最长前缀(可以是 trimmedString 本身),该前缀符合 StrDecimalLiteral 的语法规则。
  5. 返回 MV 的 Number 值

因此,numberString 成为 trimmedString 中满足 StrDecimalLiteral 语法规则的最长前缀,也就是在输入中找到的第一个可解析的数字字面量字符串。只有 . 可以用于指定浮点数。如果要接受来自不同语言环境的输入,请使用字符串替换。

function parseLocalNum(num) {
    return +(num.replace(",", "."));
}
该函数使用一元运算符而不是parseFloat,因为我认为您希望输入保持严格。 parseFloat("1ABC") 将返回 1,而使用一元运算符 +"1ABC" 则返回 NaN。这使得验证输入 MUCH 更容易。使用 parseFloat 只是猜测输入是否处于正确的格式中。

5
是的。在任何地区设置下,parseFloat("1,01") 都会返回 1 而不是 1.01 - Andy E
4
Mozilla Developer Centre 表示:"parseFloat函数将其参数(一个字符串)进行解析,并返回一个浮点数。如果它遇到一个不是正负号(+或-)、数字(0-9)、小数点或指数的字符,它会返回该字符之前的值并忽略该字符及其后续的所有字符。允许使用前导和尾随空格。" https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseFloat - Matt Sach
1
因为这已经在ECMAScript 262规范的DecimalLiteral中定义了 :) - Matt Sach
1
@Vilx- 哈哈,这不是我的话,而是ECMA国际组织的话! - Andy E
1
我会相信你的话,因为我太懒了,不想自己查规范。哈哈,谢谢!:) - Vilx-
显示剩余7条评论

15

使用:

theNumber.toLocaleString();

获取一个带有正确小数点和千位分隔符的格式化字符串


1
好的。那么我该如何解析带有这些分隔符的字符串? - Vilx-
你需要去除分隔符,并确保其符合以下格式:[+-]?([0-9]+|[0-9]*(.([eE][+-]?[0-9]+))?) - jspcal
好的,我可以删除任何必要的内容,并将特定于区域设置的分隔符替换为“.”。但是,.parseFloat()只接受“.”吗? - Vilx-
查看对Andy E原始回答的回复(简短回答:是的) - Matt Sach
我在Google Chrome中尝试了这个,但没有看到“千位分隔符”。 - jm.

2

2
此外,关于解析数字字面量的语法,请参阅旧版ECMAScript 262规范:http://bclary.com/2004/11/07/#a-7.8.3 - Anonymous
啊,是的,对于这种事情来说,有官方文档总是很好的,谢谢 :) - Matt Sach
是的,那是针对字面量的。那么解析字符串输入呢? - Vilx-
1
取一个固定的数字,例如1234.56,并运用jspcal提到的.toLocaleString()方法。检查结果以确定您的小数和千位分隔符是什么。将所有显示给用户的数字通过应用这些分隔符的函数运行(请参见我提供的链接中的示例)。 - Matt Sach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接