协慌网

登录 贡献 社区

如何在 JavaScript 中将数字格式化为美元货币字符串?

我想用 JavaScript 格式化价格。
我想要一个函数,它将float作为参数并返回一个格式如下的string

"$ 2,500.00"

最好的方法是什么?

答案

Number.prototype.toFixed

此解决方案与每个主要浏览器兼容:

const profits = 2489.8237;

  profits.toFixed(3) //returns 2489.824 (rounds up)
  profits.toFixed(2) //returns 2489.82
  profits.toFixed(7) //returns 2489.8237000 (pads the decimals)

您只需要添加货币符号(例如"$" + profits.toFixed(2) ),您将获得美元金额。

自定义功能

如果你需要使用的,每个数字之间,您可以使用此功能:

function formatMoney(n, c, d, t) {
  var c = isNaN(c = Math.abs(c)) ? 2 : c,
    d = d == undefined ? "." : d,
    t = t == undefined ? "," : t,
    s = n < 0 ? "-" : "",
    i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))),
    j = (j = i.length) > 3 ? j % 3 : 0;

  return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};

document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

像这样使用它:

(123456789.12345).formatMoney(2, ".", ",");

如果你总是要使用 '。' 和 ',',你可以让他们离开你的方法调用,该方法将为你默认它们。

(123456789.12345).formatMoney(2);

如果您的文化中有两个符号翻转(即欧洲人)并且您想使用默认值,只需在formatMoney方法中粘贴以下两行:

d = d == undefined ? "," : d, 
    t = t == undefined ? "." : t,

自定义功能(ES6)

如果您可以使用现代 ECMAScript 语法(即通过 Babel),则可以使用这个更简单的函数:

function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
  try {
    decimalCount = Math.abs(decimalCount);
    decimalCount = isNaN(decimalCount) ? 2 : decimalCount;

    const negativeSign = amount < 0 ? "-" : "";

    let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
    let j = (i.length > 3) ? i.length % 3 : 0;

    return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
  } catch (e) {
    console.log(e)
  }
};
document.getElementById("b").addEventListener("click", event => {
  document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>

简短快速的解决方案(无处不在!)

(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');  // 12,345.67

这个解决方案背后的想法是用第一个匹配和逗号替换匹配的部分,即'$&,' 。匹配是使用先行方法完成的。您可以将表达式读作“匹配一个数字,如果它后跟一个三个数字集(一个或多个)和一个点” 的序列

测试:

1        --> "1.00"
12       --> "12.00"
123      --> "123.00"
1234     --> "1,234.00"
12345    --> "12,345.00"
123456   --> "123,456.00"
1234567  --> "1,234,567.00"
12345.67 --> "12,345.67"

演示: http //jsfiddle.net/hAfMM/9571/


扩展的短解决方案

您还可以扩展Number对象的原型,以添加对任意数量的小数[0 .. n]和数字组[0 .. x]的大小的额外支持:

/**
 * Number.prototype.format(n, x)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of sections
 */
Number.prototype.format = function(n, x) {
    var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
    return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
};

1234..format();           // "1,234"
12345..format(2);         // "12,345.00"
123456.7.format(3, 2);    // "12,34,56.700"
123456.789.format(2, 4);  // "12,3456.79"

演示 / 测试: http //jsfiddle.net/hAfMM/435/


超级扩展的短解决方案

在这个超级扩展版本中,您可以设置不同的分隔符类型:

/**
 * Number.prototype.format(n, x, s, c)
 * 
 * @param integer n: length of decimal
 * @param integer x: length of whole part
 * @param mixed   s: sections delimiter
 * @param mixed   c: decimal delimiter
 */
Number.prototype.format = function(n, x, s, c) {
    var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
        num = this.toFixed(Math.max(0, ~~n));

    return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};

12345678.9.format(2, 3, '.', ',');  // "12.345.678,90"
123456.789.format(4, 4, ' ', ':');  // "12 3456:7890"
12345678.9.format(0, 3, '-');       // "12-345-679"

演示 / 测试: http //jsfiddle.net/hAfMM/612/

Intl.numberformat

Javascript 有一个数字格式化程序(Internationalization API 的一部分)。

// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  // the default value for minimumFractionDigits depends on the currency
  // and is usually already 2
});

formatter.format(2500); /* $2,500.00 */

JS 小提琴

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

Intl.NumberFormat 与 Number.prototype.toLocaleString

最后一点,将其与较旧版本进行比较。 toLocaleString 。它们都提供基本相同的功能。但是,toLocaleString 在其旧版本(pre-Intl) 中实际上并不支持区域设置 :它使用系统区域设置。因此,为了确保您使用的是正确的版本, MDN 建议检查是否存在Intl 。所以,如果你还需要检查 Intl,为什么不使用 ?但是,如果您选择使用垫片,那么也会修补到toLocaleString ,因此在这种情况下您可以毫不费力地使用它:

(2500).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
}); /* $2,500.00 */

关于浏览器支持的一些注意

  • 如今,浏览器支持不再是一个问题,在美国 / 欧盟有 97%的支持
  • 对于世界其他地区(90%支持),支持方面最大的违法者是 UC Mobile( 远离那个 )和 Opera Mini(设计瘫痪)
  • 在旧版浏览器上有一个垫片可以支持它
  • 有关更多信息,请查看CanIUse