我想用JavaScript格式化价格。我想要一个函数,它将浮点作为参数,并返回如下格式的字符串:

"$ 2,500.00"

我该怎么做?


当前回答

这可能有点晚了,但这是我刚刚为同事准备的一个方法,可以为所有数字添加一个支持区域设置的.toCurrencyString()函数。内部化仅用于数字分组,而不是货币符号-如果您输出美元,请使用提供的“$”,因为日本或中国的123 4567美元与美国的1234567美元相同。如果您输出欧元等,请将货币符号从“$”改为“$”。

在HTML<head>部分的任何地方或在需要使用它之前的任何地方声明:

  Number.prototype.toCurrencyString = function(prefix, suffix) {
    if (typeof prefix === 'undefined') { prefix = '$'; }
    if (typeof suffix === 'undefined') { suffix = ''; }
    var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/\./, '\\.') + "$");
    return prefix + (~~this).toLocaleString().replace(_localeBug, '') + (this % 1).toFixed(2).toLocaleString().replace(/^[+-]?0+/,'') + suffix;
  }

那你就完了!在需要将数字输出为货币的任何位置使用(number).toCurrencyString()。

var MyNumber = 123456789.125;
alert(MyNumber.toCurrencyString()); // alerts "$123,456,789.13"
MyNumber = -123.567;
alert(MyNumber.toCurrencyString()); // alerts "$-123.57"

其他回答

我喜欢简单:

function formatPriceUSD(price) {
    var strPrice = price.toFixed(2).toString();
    var a = strPrice.split('');

    if (price > 1000000000)
        a.splice(a.length - 12, 0, ',');

    if (price > 1000000)
        a.splice(a.length - 9, 0, ',');

    if (price > 1000)
        a.splice(a.length - 6, 0, ',');

    return '$' + a.join("");
}

此答案符合以下标准:

不依赖于外部依赖项。支持本地化。有测试/证明。使用简单和最佳的编码实践(没有复杂的正则表达式,使用标准的编码模式)。

此代码基于其他答案中的概念。如果这是一个问题的话,它的执行速度应该是最好的。

var decimalCharacter = Number("1.1").toLocaleString().substr(1,1);
var defaultCurrencyMarker = "$";
function formatCurrency(number, currencyMarker) {
    if (typeof number != "number")
        number = parseFloat(number, 10);

    // if NaN is passed in or comes from the parseFloat, set it to 0.
    if (isNaN(number))
        number = 0;

    var sign = number < 0 ? "-" : "";
    number = Math.abs(number);    // so our signage goes before the $ symbol.

    var integral = Math.floor(number);
    var formattedIntegral = integral.toLocaleString();

    // IE returns "##.00" while others return "##"
    formattedIntegral = formattedIntegral.split(decimalCharacter)[0];

    var decimal = Math.round((number - integral) * 100);
    return sign + (currencyMarker || defaultCurrencyMarker) +
        formattedIntegral  +
        decimalCharacter +
        decimal.toString() + (decimal < 10 ? "0" : "");
}

这些测试仅适用于美国语言环境机器。做出这个决定是为了简单,因为这可能会导致糟糕的输入(错误的自动定位),从而导致糟糕的输出问题。

var tests = [
    // [ input, expected result ]
    [123123, "$123,123.00"],    // no decimal
    [123123.123, "$123,123.12"],    // decimal rounded down
    [123123.126, "$123,123.13"],    // decimal rounded up
    [123123.4, "$123,123.40"],    // single decimal
    ["123123", "$123,123.00"],    // repeat subset of the above using string input.
    ["123123.123", "$123,123.12"],
    ["123123.126", "$123,123.13"],
    [-123, "-$123.00"]    // negatives
];

for (var testIndex=0; testIndex < tests.length; testIndex++) {
    var test = tests[testIndex];
    var formatted = formatCurrency(test[0]);
    if (formatted == test[1]) {
        console.log("Test passed, \"" + test[0] + "\" resulted in \"" + formatted + "\"");
    } else {
        console.error("Test failed. Expected \"" + test[1] + "\", got \"" + formatted + "\"");
    }
}

Intl.NumberFormat(国际数字格式)

JavaScript有一个数字格式器(国际化API的一部分)。

//创建我们的数字格式器。const formatter=新Intl.NumberFormat('en-US'{style:'货币',货币:'美元',//如果你想要的话,这些选项需要四舍五入到整数。//minimumFractionDigits:0,//(这对于整数足够了,但将打印2500.10作为$2500.1)//maximumFractionDigits:0,//(导致2500.99打印为$2501)});console.log(formatter.format(2500));/*$2,500.00 */

使用undefined代替第一个参数(示例中为'en-US')来使用系统区域设置(如果代码在浏览器中运行,则为用户区域设置)。区域设置代码的进一步说明。

这是货币代码列表。

Intl.NumberFormat与Number.prototype.toLocaleString

最后一点,将其与旧的.toLocaleString进行比较。它们都提供了基本相同的功能。然而,toLocaleString在其旧版本(pre-Intl)中实际上不支持区域设置:它使用系统区域设置。因此,在调试旧浏览器时,请确保使用的是正确的版本(MDN建议检查Intl的存在)。如果你不关心旧浏览器或者只使用填充程序,那么根本不需要担心这一点。

此外,对于单个项目,两者的性能是相同的,但如果要格式化大量数字,则使用Intl.NumberFormat的速度要快70倍。因此,通常最好使用Intl.NumberFormat,并在每次页面加载时仅实例化一次。无论如何,下面是toLocaleString的等效用法:

console.log((2500).toLocaleString('en-US'{style:'货币',货币:'美元',})); /* $2,500.00 */

关于浏览器支持和Node.js的一些说明

如今,浏览器支持已不再是一个问题,全球98%的支持率,美国99%,欧盟99%以上有一个垫片可以在僵化的浏览器(如Internet Explorer 8)上支持它,如果你真的需要v13之前的Node.js只支持开箱即用的en-US。一种解决方案是安装完整的icu,请参阅此处了解更多信息查看CanIUse了解更多信息

已经有好的答案了。这里有一个简单的乐趣尝试:

function currencyFormat(no) {
  var ar = (+no).toFixed(2).split('.');
  return [
      numberFormat(ar[0] | 0),
      '.',
      ar[1]
  ].join('');
}


function numberFormat(no) {
  var str = no + '';
  var ar = [];
  var i  = str.length -1;

  while(i >= 0) {
    ar.push((str[i-2] || '') + (str[i-1] || '') + (str[i] || ''));
    i = i-3;
  }
  return ar.reverse().join(',');
}

然后运行一些示例:

console.log(
  currencyFormat(1),
  currencyFormat(1200),
  currencyFormat(123),
  currencyFormat(9870000),
  currencyFormat(12345),
  currencyFormat(123456.232)
)

以下内容简洁易懂,不依赖任何过于复杂的正则表达式。

函数moneyFormat(价格,符号=“$”){const pieces=parseFloat(price).toFixed(2).split(“”)设ii=件长度-3而((ii-=3)>0){拼接件(ii,0,',')}return符号+pieces.join(“”)}控制台日志(money格式(100),money格式(1000),货币格式(10000.00),货币格式(1000000000000000000))

这是一个在最终输出中具有更多选项的版本,允许以不同的位置格式格式化不同的货币。

//高阶函数,接受期权,然后返回价格,并返回格式化的价格常量makeMoneyFormatter=({符号=“$”,分隔符=',',十进制='.',append=false,精度=2,round=真,风俗}={})=>值=>{常量=[1,10,100,1000,10000,100000,1000000,10000000]值=圆形? (数学舍入(值*e[precision])/e[precisity]):parseFloat(值)常量件=值.to固定(精度).replace('.',十进制).split(“”)设ii=工件长度-(精度?精度+1:0)而((ii-=3)>0){件.拼接(ii,0,分隔符)}if(自定义类型==“函数”){返回自定义项({签名float:值,值:pieces.join(“”)})}返回追加? pieces.join(“”)+符号:sign+pieces.join(“”)}//使用正确的格式选项创建货币转换器const formatDollar=makeMoneyFormatter()const formatPound=makeMoneyFormatter({符号:“£”,精度:0})const formatEuro=makeMoneyFormatter({符号:“€”,分隔符:“.”,十进制:',',附加:真})const customFormat=makeMoneyFormatter({圆形:假,custom:({value,float,sign})=>`SALE:$${value}USD`})控制台日志(格式磅(1000),格式美元(10000.0066),格式欧元(1000000.00),自定义格式(999999.555))