关于格式化:如何在javascript中将数字格式化为美元货币字符串?

How can I format numbers as dollars currency string in JavaScript?

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

1
"$ 2,500.00"

最好的方法是什么?


编号.原型.tofixed

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

1
2
3
4
5
  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),您的金额将以美元计算。

自定义函数

如果需要在每个数字之间使用,,则可以使用此功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
});
1
2
3
4
5
<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>

像这样使用它:

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

如果您总是要使用"."和",",您可以将它们从方法调用中去掉,并且该方法将为您默认它们。

1
(123456789.12345).formatMoney(2);

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

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

自定义函数(ES6)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);
});
1
2
3
4
5
<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>


短而快速的解决方案(适用于所有地方!)

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

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

测验:

1
2
3
4
5
6
7
8
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]大小的额外支持:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * 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/

超长短解

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * 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/


国际号码格式

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

1
2
3
4
5
6
7
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

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

JS小提琴

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

intl.numberFormat与number.prototype.toLocalString

最后一个注释,将其与旧的.toLocaleString进行比较。它们都提供基本相同的功能。但是,toLocalString在其旧版本(pre-intl)中实际上不支持区域设置:它使用系统区域设置。因此,请确保您使用的是正确的版本(MDN建议检查是否存在Intl)。另外,两种方法在单个项目中的性能是相同的,但是如果要格式化的数字很多,那么使用Intl.NumberFormat的速度要快70倍。以下是如何使用toLocaleString

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

关于浏览器支持的一些说明

  • 现在浏览器支持已不再是一个问题,在美国/欧盟有97%的支持率
  • 对于世界其他地区(92%的支持率),在支持方面最大的违规者是UC Mobile(远离它)和Opera Mini(因设计而瘫痪)。
  • 有一个填充程序可以在旧浏览器上支持它
  • 了解更多信息


看看javascript数字对象,看看它是否能帮助您。

  • toLocaleString()将使用特定位置的千位分隔符来格式化数字。
  • toFixed()将数字四舍五入到指定的小数位数。

要同时使用这些,值的类型必须改回数字,因为它们都输出字符串。

例子:

1
Number(someNumber.toFixed(1)).toLocaleString()


下面是patrick desjardins(别名daok)代码,添加了一些注释和一些小改动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
decimal_sep: character used as deciaml separtor, it defaults to '.' when omitted
thousands_sep: char used as thousands separator, it defaults to ',' when omitted
*/

Number.prototype.toMoney = function(decimals, decimal_sep, thousands_sep)
{
   var n = this,
   c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
   d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)

   /*
   according to [https://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
   the fastest way to check for not defined parameter is to use typeof value === 'undefined'
   rather than doing value === undefined.
   */
 
   t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value

   sign = (n < 0) ? '-' : '',

   //extracting the absolute value of the integer part of the number and converting to string
   i = parseInt(n = Math.abs(n).toFixed(c)) + '',

   j = ((j = i.length) > 3) ? j % 3 : 0;
   return sign + (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) : '');
}

这里有一些测试:

1
2
3
4
5
6
7
8
9
10
11
12
//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert(123456789.67392.toMoney() + '
'
+ 123456789.67392.toMoney(3) + '
'
+ 123456789.67392.toMoney(0) + '
'
+ (123456).toMoney() + '
'
+ (123456).toMoney(0) + '
'
+ 89.67392.toMoney() + '
'
+ (89).toMoney());

//some tests (do not forget parenthesis when using negative numbers and number with no decimals)
alert((-123456789.67392).toMoney() + '
'
+ (-123456789.67392).toMoney(-3));

次要变化包括:

  • 移动一点Math.abs(decimals),只有在不使用NaN的情况下才进行。

  • decimal_sep不能再是空字符串(必须有某种十进制分隔符)

  • 我们使用typeof thousands_sep === 'undefined',正如如何最好地确定参数是否没有发送到javascript函数中所建议的那样。

  • 不需要(+n || 0),因为thisNumber对象。

  • JS小提琴


    accounting.js是一个用于数字、货币和货币格式的小型JavaScript库。


    如果金额是数字,比如-123,那么

    1
    amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });

    将生成字符串"-$123.00"

    下面是一个完整的工作示例。


    这是我见过的最好的JS货币格式化工具:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator) {
        var n = this,
            decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
            decSeparator = decSeparator == undefined ?"." : decSeparator,
            thouSeparator = thouSeparator == undefined ?"," : thouSeparator,
            sign = n < 0 ?"-" :"",
            i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) +"",
            j = (j = i.length) > 3 ? j % 3 : 0;
        return sign + (j ? i.substr(0, j) + thouSeparator :"") + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) :"");
    };

    它被重新格式化并从这里借用:https://stackoverflow.com/a/149099/751484

    你必须提供你自己的货币代号(你用的是美元)。

    这样称呼它(尽管请注意,参数默认为2、逗号和句点,因此如果您喜欢,则不需要提供任何参数):

    1
    2
    var myMoney=3543.75873;
    var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); //"$3,543.76"


    这里已经有了一些很好的答案。这是另一个尝试,只是为了好玩:

    1
    2
    3
    4
    5
    6
    function formatDollar(num) {
        var p = num.toFixed(2).split(".");
        return"$" + p[0].split("").reverse().reduce(function(acc, num, i, orig) {
            return  num=="-" ? acc : num + (i && !(i % 3) ?"," :"") + acc;
        },"") +"." + p[1];
    }

    一些测试:

    1
    2
    3
    4
    5
    formatDollar(45664544.23423) //"$45,664,544.23"
    formatDollar(45) //"$45.00"
    formatDollar(123) //"$123.00"
    formatDollar(7824) //"$7,824.00"
    formatDollar(1) //"$1.00"

    编辑:现在它也将处理负数


    我想你想要的是f.nettotal.value ="$" + showValue.toFixed(2);


    为什么没有人提出以下建议?

    1
    (2500).toLocaleString("en-GB", {style:"currency", currency:"GBP", minimumFractionDigits: 2})

    适用于大多数/部分浏览器:

    https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_-objects/number/toLocaleString浏览器兼容性


    numeral.js-一个JS库,可通过@adamwrapper轻松设置数字格式

    1
    numeral(23456.789).format('$0,0.00'); // ="$23,456.79"


    我使用(来自微软的)图书馆全球化:

    这是一个伟大的项目,本地化的数字,货币和日期,并让他们根据用户的地区自动格式化正确的方式!…尽管它应该是jquery扩展,但它目前是一个100%独立的库。我建议你们都试试看!:)


    好吧,根据你说的,我用这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1);

    var AmountWithCommas = Amount.toLocaleString();
    var arParts = String(AmountWithCommas).split(DecimalSeparator);
    var intPart = arParts[0];
    var decPart = (arParts.length > 1 ? arParts[1] : '');
    decPart = (decPart + '00').substr(0,2);

    return '£ ' + intPart + DecimalSeparator + decPart;

    我愿意接受改进建议(我不希望只包括Yui这样做:)我已经知道我应该检测"."而不是仅仅使用它作为小数点分隔符…


    javascript数字格式化程序(以前在谷歌代码)

    • 短、快、灵活但独立。只有75行,包括MIT许可证信息、空白行和注释。
    • 接受标准数字格式,如#,##0.00或带否定的-000.####
    • 接受任何国家格式,如# ##0,00#,###.###'###.##或任何类型的非编号符号。
    • 接受任何数字分组。#,##,#0.000#,###0.##均有效。
    • 接受任何冗余/防误格式。##,###,##.#0#,#00#.###0#都可以。
    • 自动编号舍入。
    • 简单的界面,只需提供这样的掩码和值:format("0.0000", 3.141592)
    • 在掩码中包含前缀和后缀

    (摘自自述文件)


    +1.向乔纳森M提供原始方法。由于这显然是一个货币格式化程序,所以我继续向输出中添加了货币符号(默认为"$"),并添加了一个默认逗号作为千位分隔符。如果您实际上不需要货币符号(或千位分隔符),只需使用"(空字符串)作为参数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Number.prototype.formatMoney = function(decPlaces, thouSeparator, decSeparator, currencySymbol) {
        // check the args and supply defaults:
        decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
        decSeparator = decSeparator == undefined ?"." : decSeparator;
        thouSeparator = thouSeparator == undefined ?"," : thouSeparator;
        currencySymbol = currencySymbol == undefined ?"$" : currencySymbol;

        var n = this,
            sign = n < 0 ?"-" :"",
            i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) +"",
            j = (j = i.length) > 3 ? j % 3 : 0;

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


    有一个PHP函数"数字格式"的javascript端口。

    我发现它非常有用,因为它易于使用,并且对PHP开发人员来说是可识别的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    function number_format (number, decimals, dec_point, thousands_sep) {
        var n = number, prec = decimals;

        var toFixedFix = function (n,prec) {
            var k = Math.pow(10,prec);
            return (Math.round(n*k)/k).toString();
        };

        n = !isFinite(+n) ? 0 : +n;
        prec = !isFinite(+prec) ? 0 : Math.abs(prec);
        var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
        var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;

        var s = (prec > 0) ? toFixedFix(n, prec) : toFixedFix(Math.round(n), prec);
        //fix for IE parseFloat(0.55).toFixed(0) = 0;

        var abs = toFixedFix(Math.abs(n), prec);
        var _, i;

        if (abs >= 1000) {
            _ = abs.split(/\D/);
            i = _[0].length % 3 || 3;

            _[0] = s.slice(0,i + (n < 0)) +
                   _[0].slice(i).replace(/(\d{3})/g, sep+'$1');
            s = _.join(dec);
        } else {
            s = s.replace('.', dec);
        }

        var decPos = s.indexOf(dec);
        if (prec >= 1 && decPos !== -1 && (s.length-decPos-1) < prec) {
            s += new Array(prec-(s.length-decPos-1)).join(0)+'0';
        }
        else if (prec >= 1 && decPos === -1) {
            s += dec+new Array(prec).join(0)+'0';
        }
        return s;
    }

    (注释块与原文不符,下面包含示例和信用证(如有到期)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // Formats a number with grouped thousands
    //
    // version: 906.1806
    // discuss at: http://phpjs.org/functions/number_format
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +     input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +     improved by: davook
    // +     improved by: Brett Zamir (http://brett-zamir.me)
    // +     input by: Jay Klehr
    // +     improved by: Brett Zamir (http://brett-zamir.me)
    // +     input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *     example 10: number_format('1.20', 2);
    // *     returns 10: '1.20'
    // *     example 11: number_format('1.20', 4);
    // *     returns 11: '1.2000'
    // *     example 12: number_format('1.2000', 3);
    // *     returns 12: '1.200'


    使用正则表达式的较短方法(用于插入空格、逗号或点)?

    1
    2
    3
    4
    5
    6
        Number.prototype.toCurrencyString=function(){
            return this.toFixed(2).replace(/(\d)(?=(\d{3})+\b)/g,'$1 ');
        }

        n=12345678.9;
        alert(n.toCurrencyString());

    有一个内置的function固定在javascript中。

    1
    2
    var num = new Number(349);
    document.write("$" + num.toFixed(2));


    Patrick Desjardins的答案看起来不错,但我更喜欢简单的javascript。这是我刚写的一个函数,它接受一个数字并以货币格式返回(减去美元符号)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // Format numbers to two decimals with commas
    function formatDollar(num) {
        var p = num.toFixed(2).split(".");
        var chars = p[0].split("").reverse();
        var newstr = '';
        var count = 0;
        for (x in chars) {
            count++;
            if(count%3 == 1 && count != 1) {
                newstr = chars[x] + ',' + newstr;
            } else {
                newstr = chars[x] + newstr;
            }
        }
        return newstr +"." + p[1];
    }

    我建议使用Google可视化API中的数字格式类。

    你可以这样做:

    1
    2
    3
    4
    5
    6
    var formatter = new google.visualization.NumberFormat({
        prefix: '$',
        pattern: '#,###,###.##'
    });

    formatter.formatValue(1000000); // $ 1,000,000

    希望能有所帮助。


    没见过这个。它非常简洁易懂。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function moneyFormat(price, sign = '$') {
      const pieces = parseFloat(price).toFixed(2).split('')
      let ii = pieces.length - 3
      while ((ii-=3) > 0) {
        pieces.splice(ii, 0, ',')
      }
      return sign + pieces.join('')
    }

    console.log(
      moneyFormat(100),
      moneyFormat(1000),
      moneyFormat(10000.00),
      moneyFormat(1000000000000000000)
    )

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    // higher order function that takes options then a price and will return the formatted price
    const makeMoneyFormatter = ({
      sign = '$',
      delimiter = ',',
      decimal = '.',
      append = false,
      precision = 2,
      round = true,
      custom
    } = {}) => value => {
     
      const e = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
     
      value = round
        ? (Math.round(value * e[precision]) / e[precision])
        : parseFloat(value)
     
      const pieces = value
        .toFixed(precision)
        .replace('.', decimal)
        .split('')
     
      let ii = pieces.length - (precision ? precision + 1 : 0)
     
      while ((ii-=3) > 0) {
        pieces.splice(ii, 0, delimiter)
      }
     
      if (typeof custom === 'function') {
        return custom({
          sign,
          float: value,
          value: pieces.join('')
        })
      }
     
      return append
        ? pieces.join('') + sign
        : sign + pieces.join('')
    }

    // create currency converters with the correct formatting options
    const formatDollar = makeMoneyFormatter()
    const formatPound = makeMoneyFormatter({
      sign: '£',
      precision: 0
    })
    const formatEuro = makeMoneyFormatter({
      sign: '€',
      delimiter: '.',
      decimal: ',',
      append: true
    })

    const customFormat = makeMoneyFormatter({
      round: false,
      custom: ({ value, float, sign }) => `SALE:$${value}USD`
    })

    console.log(
      formatPound(1000),
      formatDollar(10000.0066),
      formatEuro(100000.001),
      customFormat(999999.555)
    )


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function CurrencyFormatted(amount)
    {
        var i = parseFloat(amount);
        if(isNaN(i)) { i = 0.00; }
        var minus = '';
        if(i < 0) { minus = '-'; }
        i = Math.abs(i);
        i = parseInt((i + .005) * 100);
        i = i / 100;
        s = new String(i);
        if(s.indexOf('.') < 0) { s += '.00'; }
        if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
        s = minus + s;
        return s;
    }

    来自Willmaster。


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

    在您需要使用它之前,在您头脑中的任何地方或任何必要的地方声明:

    1
    2
    3
    4
    5
    6
      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()

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


    主要部分是插入千个分隔符,可以这样做:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <script type="text/javascript">
    function ins1000Sep(val){
      val = val.split(".");
      val[0] = val[0].split("").reverse().join("");
      val[0] = val[0].replace(/(\d{3})/g,"$1,");
      val[0] = val[0].split("").reverse().join("");
      val[0] = val[0].indexOf(",")==0?val[0].substring(1):val[0];
      return val.join(".");
    }
    function rem1000Sep(val){
      return val.replace(/,/g,"");
    }
    function formatNum(val){
      val = Math.round(val*100)/100;
      val = (""+val).indexOf(".")>-1 ? val +"00" : val +".00";
      var dec = val.indexOf(".");
      return dec == val.length-3 || dec == 0 ? val : val.substring(0,dec+3);
    }


    <button onclick="alert(ins1000Sep(formatNum(12313231)));">


    这里有一些解决方案,都通过了测试套件,测试套件和基准包括在内,如果你想复制粘贴到测试,请尝试这个要点。

    方法0(regexp)

    基于https://stackoverflow.com/a/14428340/1877620,但如果没有小数点,则修复。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }

            var a = this.toFixed(precision).split('.');
            a[0] = a[0].replace(/\d(?=(\d{3})+$)/g, '$&,');
            return a.join('.');
        }
    }

    方法1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }

            var a = this.toFixed(precision).split('.'),
                // skip the '-' sign
                head = Number(this < 0);

            // skip the digits that's before the first thousands separator
            head += (a[0].length - head) % 3 || 3;

            a[0] = a[0].slice(0, head) + a[0].slice(head).replace(/\d{3}/g, ',$&');
            return a.join('.');
        };
    }

    方法2(拆分为数组)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }

            var a = this.toFixed(precision).split('.');

            a[0] = a[0]
                .split('').reverse().join('')
                .replace(/\d{3}(?=\d)/g, '$&,')
                .split('').reverse().join('');

            return a.join('.');
        };
    }

    方法3(循环)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    if (typeof Number.prototype.format === 'undefined') {
        Number.prototype.format = function (precision) {
            if (!isFinite(this)) {
                return this.toString();
            }

            var a = this.toFixed(precision).split('');
            a.push('.');

            var i = a.indexOf('.') - 3;
            while (i > 0 && a[i-1] !== '-') {
                a.splice(i, 0, ',');
                i -= 3;
            }

            a.pop();
            return a.join('');
        };
    }

    使用实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    console.log('======== Demo ========')
    console.log(
        (1234567).format(0),
        (1234.56).format(2),
        (-1234.56).format(0)
    );
    var n = 0;
    for (var i=1; i<20; i++) {
        n = (n * 10) + (i % 10)/100;
        console.log(n.format(2), (-n).format(2));
    }

    分离器

    如果我们需要自定义千位分隔符或十进制分隔符,请使用replace()

    1
    123456.78.format(2).replace(',', ' ').replace('.', ' ');

    测试套件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    function assertEqual(a, b) {
        if (a !== b) {
            throw a + ' !== ' + b;
        }
    }

    function test(format_function) {
        console.log(format_function);
        assertEqual('NaN', format_function.call(NaN, 0))
        assertEqual('Infinity', format_function.call(Infinity, 0))
        assertEqual('-Infinity', format_function.call(-Infinity, 0))

        assertEqual('0', format_function.call(0, 0))
        assertEqual('0.00', format_function.call(0, 2))
        assertEqual('1', format_function.call(1, 0))
        assertEqual('-1', format_function.call(-1, 0))
        // decimal padding
        assertEqual('1.00', format_function.call(1, 2))
        assertEqual('-1.00', format_function.call(-1, 2))
        // decimal rounding
        assertEqual('0.12', format_function.call(0.123456, 2))
        assertEqual('0.1235', format_function.call(0.123456, 4))
        assertEqual('-0.12', format_function.call(-0.123456, 2))
        assertEqual('-0.1235', format_function.call(-0.123456, 4))
        // thousands separator
        assertEqual('1,234', format_function.call(1234.123456, 0))
        assertEqual('12,345', format_function.call(12345.123456, 0))
        assertEqual('123,456', format_function.call(123456.123456, 0))
        assertEqual('1,234,567', format_function.call(1234567.123456, 0))
        assertEqual('12,345,678', format_function.call(12345678.123456, 0))
        assertEqual('123,456,789', format_function.call(123456789.123456, 0))
        assertEqual('-1,234', format_function.call(-1234.123456, 0))
        assertEqual('-12,345', format_function.call(-12345.123456, 0))
        assertEqual('-123,456', format_function.call(-123456.123456, 0))
        assertEqual('-1,234,567', format_function.call(-1234567.123456, 0))
        assertEqual('-12,345,678', format_function.call(-12345678.123456, 0))
        assertEqual('-123,456,789', format_function.call(-123456789.123456, 0))
        // thousands separator and decimal
        assertEqual('1,234.12', format_function.call(1234.123456, 2))
        assertEqual('12,345.12', format_function.call(12345.123456, 2))
        assertEqual('123,456.12', format_function.call(123456.123456, 2))
        assertEqual('1,234,567.12', format_function.call(1234567.123456, 2))
        assertEqual('12,345,678.12', format_function.call(12345678.123456, 2))
        assertEqual('123,456,789.12', format_function.call(123456789.123456, 2))
        assertEqual('-1,234.12', format_function.call(-1234.123456, 2))
        assertEqual('-12,345.12', format_function.call(-12345.123456, 2))
        assertEqual('-123,456.12', format_function.call(-123456.123456, 2))
        assertEqual('-1,234,567.12', format_function.call(-1234567.123456, 2))
        assertEqual('-12,345,678.12', format_function.call(-12345678.123456, 2))
        assertEqual('-123,456,789.12', format_function.call(-123456789.123456, 2))
    }

    console.log('======== Testing ========');
    test(Number.prototype.format);
    test(Number.prototype.format1);
    test(Number.prototype.format2);
    test(Number.prototype.format3);

    基准

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    function benchmark(f) {
        var start = new Date().getTime();
        f();
        return new Date().getTime() - start;
    }

    function benchmark_format(f) {
        console.log(f);
        time = benchmark(function () {
            for (var i = 0; i < 100000; i++) {
                f.call(123456789, 0);
                f.call(123456789, 2);
            }
        });
        console.log(time.format(0) + 'ms');
    }

    // if not using async, browser will stop responding while running.
    // this will create a new thread to benchmark
    async = [];
    function next() {
        setTimeout(function () {
            f = async.shift();
            f && f();
            next();
        }, 10);
    }

    console.log('======== Benchmark ========');
    async.push(function () { benchmark_format(Number.prototype.format); });
    next();


    通常,有多种方法可以做相同的事情,但我会避免使用Number.prototype.toLocaleString,因为它可以根据用户设置返回不同的值。

    我也不建议扩展Number.prototype——扩展本机对象原型是一种糟糕的做法,因为它可能会与其他人的代码(如库/框架/插件)发生冲突,并且可能与未来的javascript实现/版本不兼容。

    我相信正则表达式是解决这个问题的最佳方法,下面是我的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     * Converts number into currency format
     * @param {number} number   Number that should be converted.
     * @param {string} [decimalSeparator]    Decimal separator, defaults to '.'.
     * @param {string} [thousandsSeparator]    Thousands separator, defaults to ','.
     * @param {int} [nDecimalDigits]    Number of decimal digits, defaults to `2`.
     * @return {string} Formatted string (e.g. numberToCurrency(12345.67) returns '12,345.67')
     */

    function numberToCurrency(number, decimalSeparator, thousandsSeparator, nDecimalDigits){
        //default values
        decimalSeparator = decimalSeparator || '.';
        thousandsSeparator = thousandsSeparator || ',';
        nDecimalDigits = nDecimalDigits == null? 2 : nDecimalDigits;

        var fixed = number.toFixed(nDecimalDigits), //limit/add decimal digits
            parts = new RegExp('^(-?\\d{1,3})((?:\\d{3})+)(\\.(\\d{'+ nDecimalDigits +'}))?$').exec( fixed ); //separate begin [$1], middle [$2] and decimal digits [$4]

        if(parts){ //number >= 1000 || number <= -1000
            return parts[1] + parts[2].replace(/\d{3}/g, thousandsSeparator + '$&') + (parts[4] ? decimalSeparator + parts[4] : '');
        }else{
            return fixed.replace('.', decimalSeparator);
        }
    }

    2010/08/30编辑:增加了设置小数位数的选项。2011/08/23编辑:增加了将小数位数设置为零的选项。


    我从:accounting.js找到这个。它非常简单,完全符合我的需要。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Default usage:
    accounting.formatMoney(12345678); // $12,345,678.00

    // European formatting (custom symbol and separators), can also use options object as second parameter:
    accounting.formatMoney(4999.99,"€", 2,".",","); // €4.999,99

    // Negative values can be formatted nicely:
    accounting.formatMoney(-500000,"£", 0); // £ -500,000

    // Simple `format` string allows control of symbol position (%v = value, %s = symbol):
    accounting.formatMoney(5318008, { symbol:"GBP",  format:"%v %s" }); // 5,318,008.00 GBP

    // Euro currency symbol to the right
    accounting.formatMoney(5318008, {symbol:"€", precision: 2, thousand:".", decimal :",", format:"%v%s"}); // 1.008,00€


    通过首先反转字符串和基本regexp来正确放置逗号的简单选项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String.prototype.reverse = function() {
        return this.split('').reverse().join('');
    };

    Number.prototype.toCurrency = function( round_decimal /*boolean*/ ) {      
         // format decimal or round to nearest integer
         var n = this.toFixed( round_decimal ? 0 : 2 );

         // convert to a string, add commas every 3 digits from left to right
         // by reversing string
         return (n + '').reverse().replace( /(\d{3})(?=\d)/g, '$1,' ).reverse();
    };

    Patrick Desjardins(前Daok)的例子对我很有用。如果有人感兴趣的话,我就去咖啡店。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Number.prototype.toMoney = (decimals = 2, decimal_separator =".", thousands_separator =",") ->
        n = this
        c = if isNaN(decimals) then 2 else Math.abs decimals
        sign = if n < 0 then"-" else""
        i = parseInt(n = Math.abs(n).toFixed(c)) + ''
        j = if (j = i.length) > 3 then j % 3 else 0
        x = if j then i.substr(0, j) + thousands_separator else ''
        y = i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + thousands_separator)
        z = if c then decimal_separator + Math.abs(n - i).toFixed(c).slice(2) else ''
        sign + x + y + z

    YUI代码库使用以下格式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    format: function(nData, oConfig) {
        oConfig = oConfig || {};

        if(!YAHOO.lang.isNumber(nData)) {
            nData *= 1;
        }

        if(YAHOO.lang.isNumber(nData)) {
            var sOutput = nData +"";
            var sDecimalSeparator = (oConfig.decimalSeparator) ? oConfig.decimalSeparator :".";
            var nDotIndex;

            // Manage decimals
            if(YAHOO.lang.isNumber(oConfig.decimalPlaces)) {
                // Round to the correct decimal place
                var nDecimalPlaces = oConfig.decimalPlaces;
                var nDecimal = Math.pow(10, nDecimalPlaces);
                sOutput = Math.round(nData*nDecimal)/nDecimal +"";
                nDotIndex = sOutput.lastIndexOf(".");

                if(nDecimalPlaces > 0) {
                    // Add the decimal separator
                    if(nDotIndex < 0) {
                        sOutput += sDecimalSeparator;
                        nDotIndex = sOutput.length-1;
                    }
                    // Replace the"."
                    else if(sDecimalSeparator !=="."){
                        sOutput = sOutput.replace(".",sDecimalSeparator);
                    }
                    // Add missing zeros
                    while((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) {
                        sOutput +="0";
                    }
                }
            }

            // Add the thousands separator
            if(oConfig.thousandsSeparator) {
                var sThousandsSeparator = oConfig.thousandsSeparator;
                nDotIndex = sOutput.lastIndexOf(sDecimalSeparator);
                nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length;
                var sNewOutput = sOutput.substring(nDotIndex);
                var nCount = -1;
                for (var i=nDotIndex; i>0; i--) {
                    nCount++;
                    if ((nCount%3 === 0) && (i !== nDotIndex)) {
                        sNewOutput = sThousandsSeparator + sNewOutput;
                    }
                    sNewOutput = sOutput.charAt(i-1) + sNewOutput;
                }
                sOutput = sNewOutput;
            }

            // Prepend prefix
            sOutput = (oConfig.prefix) ? oConfig.prefix + sOutput : sOutput;

            // Append suffix
            sOutput = (oConfig.suffix) ? sOutput + oConfig.suffix : sOutput;

            return sOutput;
        }
        // Still not a Number, just return unaltered
        else {
            return nData;
        }
    }

    它需要编辑,因为yui库是可配置的,比如用"."替换oconfig.decimalsparator。


    55个答案显然是在寻求另一个答案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
            function centsToDollaString(x){
              var cents = x +""
              while(cents.length < 4){
                cents ="0" + cents;
              }
              var dollars = cents.substr(0,cents.length - 2)
              var decimal = cents.substr(cents.length - 2, 2)
              while(dollars.length % 3 != 0){
                dollars ="0" + dollars;
              }
              str = dollars.replace(/(\d{3})(?=\d)/g,"$1" +",").replace(/^0*(?=.)/,"");
              return"$" + str +"." + decimal;
            }

    @TGgagne是正确的。我下面的解决方案不好,因为浮动舍入。toLocaleString功能缺乏浏览器支持。我将留下以下评论,以备存档,以备不时之需。:)

    https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_-objects/date/toLocaleString浏览器兼容性

    (旧解决方案)使用Patrick Desjardins解决方案。

    这是一个使用toLocaleString()的简单解决方案,自Javascript 1.0版起就得到了支持。此示例将货币指定为美元,但可以使用"英镑"而不是"美元"将其转换为英镑。

    1
    2
    3
    4
    5
    6
    var formatMoney = function (value) {
        // Convert the value to a floating point number in case it arrives as a string.
        var numeric = parseFloat(value);
        // Specify the local currency.
        return numeric.toLocaleString('USD', { style: 'currency', currency:"USD", minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }

    更多详情请参见https://marcoscaceres.github.io/jsi18n/本地化货币。


    用于处理货币输出(包括负数)的函数。

    样本输出:
    5.23美元< BR>- 5.23美元

    1
    2
    3
    4
    5
    6
    7
    8
    function formatCurrency(total) {
        var neg = false;
        if(total < 0) {
            neg = true;
            total = Math.abs(total);
        }
        return (neg ?"-$" : '$') + parseFloat(total, 10).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,"$1,").toString();
    }


    http://code.google.com/p/javascript-number-formatter/:

    • 短、快、灵活但独立。只有75行,包括MIT许可证信息、空白行和注释。
    • 接受标准数字格式,如、0.00或带负号-000。。
    • 接受任何国家格式,如或任何类型的非编号符号。
    • 接受任何数字分组。#、、0.000或、0.均有效。
    • 接受任何冗余/防误格式。##、、或0、00 0都还好。
    • 自动编号舍入。
    • 简单的界面,只需提供如下的掩码和值:格式("0.0000",3.141592)

    更新这是我自己开发的用于最常见任务的pp实用程序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    var NumUtil = {};

    /**
      Petty print 'num' wth exactly 'signif' digits.
      pp(123.45, 2) =="120"
      pp(0.012343, 3) =="0.0123"
      pp(1.2, 3) =="1.20"
    */

    NumUtil.pp = function(num, signif) {
        if (typeof(num) !=="number")
            throw 'NumUtil.pp: num is not a number!';
        if (isNaN(num))
            throw 'NumUtil.pp: num is NaN!';
        if (num < 1e-15 || num > 1e15)
            return num;
        var r = Math.log(num)/Math.LN10;
        var dot = Math.floor(r) - (signif-1);
        r = r - Math.floor(r) + (signif-1);
        r = Math.round(Math.exp(r * Math.LN10)).toString();
        if (dot >= 0) {
            for (; dot > 0; dot -= 1)
                r +="0";
            return r;
        } else if (-dot >= r.length) {
            var p ="0.";
            for (; -dot > r.length; dot += 1) {
                p +="0";
            }
            return p+r;
        } else {
            return r.substring(0, r.length + dot) +"." + r.substring(r.length + dot);
        }
    }

    /** Append leading zeros up to 2 digits. */
    NumUtil.align2 = function(v) {
        if (v < 10)
            return"0"+v;
        return""+v;
    }
    /** Append leading zeros up to 3 digits. */
    NumUtil.align3 = function(v) {
        if (v < 10)
            return"00"+v;
        else if (v < 100)
            return"0"+v;
        return""+v;
    }

    NumUtil.integer = {};

    /** Round to integer and group by 3 digits. */
    NumUtil.integer.pp = function(num) {
        if (typeof(num) !=="number") {
            console.log("%s", new Error().stack);
            throw 'NumUtil.integer.pp: num is not a number!';
        }
        if (isNaN(num))
            throw 'NumUtil.integer.pp: num is NaN!';
        if (num > 1e15)
            return num;
        if (num < 0)
            throw 'Negative num!';
        num = Math.round(num);
        var group = num % 1000;
        var integ = Math.floor(num / 1000);
        if (integ === 0) {
            return group;
        }
        num = NumUtil.align3(group);
        while (true) {
            group = integ % 1000;
            integ = Math.floor(integ / 1000);
            if (integ === 0)
                return group +"" + num;
            num = NumUtil.align3(group) +"" + num;
        }
        return num;
    }

    NumUtil.currency = {};

    /** Round to coins and group by 3 digits. */
    NumUtil.currency.pp = function(amount) {
        if (typeof(amount) !=="number")
            throw 'NumUtil.currency.pp: amount is not a number!';
        if (isNaN(amount))
            throw 'NumUtil.currency.pp: amount is NaN!';
        if (amount > 1e15)
            return amount;
        if (amount < 0)
            throw 'Negative amount!';
        if (amount < 1e-2)
            return 0;
        var v = Math.round(amount*100);
        var integ = Math.floor(v / 100);
        var frac = NumUtil.align2(v % 100);
        var group = integ % 1000;
        integ = Math.floor(integ / 1000);
        if (integ === 0) {
            return group +"." + frac;
        }
        amount = NumUtil.align3(group);
        while (true) {
            group = integ % 1000;
            integ = Math.floor(integ / 1000);
            if (integ === 0)
                return group +"" + amount +"." + frac;
            amount = NumUtil.align3(group) +"" + amount;
        }
        return amount;
    }


    国际号码格式

    1
    2
    3
    var number = 3500;
    alert(new Intl.NumberFormat().format(number));
    // →"3,500" if in US English locale

    或phpjs.com/functions/number_格式


    此答案符合以下标准:

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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" :"");
    }

    这些测试只在美国本地机器上工作。这个决定是为了简单起见,因为这可能导致错误的输入(错误的自动本地化),从而导致错误的输出问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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 +""");
        }
    }

    https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/numberformat示例:使用区域设置

    此示例显示本地化数字格式中的一些变体。要获取应用程序用户界面中使用的语言的格式,请确保使用locales参数指定该语言(可能还有一些回退语言):

    var number = 123456.789;

    // German uses comma as decimal separator and period for thousands
    console.log(new Intl.NumberFormat('de-DE').format(number)); // →
    123.456,789

    // Arabic in most Arabic speaking countries uses real Arabic digits
    console.log(new Intl.NumberFormat('ar-EG').format(number)); // →
    ??????????

    // India uses thousands/lakh/crore separators console.log(new
    Intl.NumberFormat('en-IN').format(number));


    下面是将数字转换为货币格式的最佳方法:

    1
    2
    3
    4
    5
    function toCurrency(amount){
        return amount.replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,");
    }

    // usage: toCurrency(3939920.3030);

    干杯!阿努伊


    Jonathan M的代码对我来说很复杂,所以我重写了它,在FF V30上得到了30%,在Chrome V35速度提升上得到了60%(http://jsperf.com/number-formating2):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
        decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
        decSeparator = decSeparator == undefined ?"." : decSeparator;
        thouSeparator = thouSeparator == undefined ?"," : thouSeparator;

        var n = this.toFixed(decPlaces);
        if (decPlaces) {
            var i = n.substr(0, n.length - (decPlaces + 1));
            var j = decSeparator + n.substr(-decPlaces);
        } else {
            i = n;
            j = '';
        }

        function reverse(str) {
            var sr = '';
            for (var l = str.length - 1; l >= 0; l--) {
                sr += str.charAt(l);
            }
            return sr;
        }

        if (parseInt(i)) {
            i = reverse(reverse(i).replace(/(\d{3})(?=\d)/g,"$1" + thouSeparator));
        }
        return i+j;
    };

    用途:

    1
    2
    var sum = 123456789.5698;
    var formatted = '$' + sum.formatNumber(2,',','.'); //"$123,456,789.57"

    1
    2
    3
    Number(value)
            .toFixed(2)
            .replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1,")


    符合原始要求的极简方法:

    1
    2
    3
    function formatMoney(n) {
        return"$" + (Math.round(n * 100) / 100).toLocaleString();
    }

    @丹尼尔·马格里奥拉:你说得对,上面是一个草率的,不完整的实施。以下是正确的实施:

    1
    2
    3
    4
    function formatMoney(n) {
        return"$" + n.toLocaleString().split(".")[0] +"."
            + n.toFixed(2).split(".")[1];
    }


    下面是一个来自xmilley提供的代码的moooltools1.2实现…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Number.implement('format', function(decPlaces, thouSeparator, decSeparator){
    decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
    decSeparator = decSeparator === undefined ? '.' : decSeparator;
    thouSeparator = thouSeparator === undefined ? ',' : thouSeparator;

    var num = this,
        sign = num < 0 ? '-' : '',
        i = parseInt(num = Math.abs(+num || 0).toFixed(decPlaces)) + '',
        j = (j = i.length) > 3 ? j % 3 : 0;

    return sign + (j ? i.substr(0, j) + thouSeparator : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thouSeparator) + (decPlaces ? decSeparator + Math.abs(num - i).toFixed(decPlaces).slice(2) : '');
    });

    ToLocalString很好,但不能在所有浏览器上使用。我通常使用currencyformatter.js(https://osrec.github.io/currencyformatter.js/)。它非常轻,包含了所有的货币和语言环境定义。它还擅长格式化格式异常的货币,如印度卢比(按百万和千万卢比分组)。也没有依赖关系!

    OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' });
    // Returns ? 25,34,234.00

    OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR' });
    // Returns 2.534.234,00 €

    OSREC.CurrencyFormatter.format(2534234, { currency: 'EUR', locale: 'fr' });
    // Returns 2 534 234,00 €


    在javascript中没有"formatNumber"的等价物。你可以自己写或者找到一个已经这样做的库。


    这可能有效:

    1
    2
    3
    function format_currency(v, number_of_decimals, decimal_separator, currency_sign){
      return (isNaN(v)? v : currency_sign + parseInt(v||0).toLocaleString() + decimal_separator + (v*1).toFixed(number_of_decimals).slice(-number_of_decimals));
    }

    没有循环,没有正则表达式,没有数组,没有奇异的条件。


    雷杰普的诡计?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Number.prototype.toMonetaryString=function(){var n=this.toFixed(2),m;
    // var=this.toFixed(2).replace(/\./,','); for comma separator
    // with a space for thousands separator
      while ((m=n.replace(/(\d)(\d\d\d)\b/g,'$1 $2'))!=n) n=m;
      return m;
    }
    String.prototype.fromMonetaryToNumber=function(s){
      return this.replace(/[^\d-]+/g,'')/100;
    }

    因为为什么不添加另一个答案呢?我在很大程度上基于视觉的答案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function format (val) {
      val = (+val).toLocaleString();
      val = (+val).toFixed(2);
      val +="";
      return val.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g,"$1" + format.thousands);
    }
    (function (isUS) {
      format.decimal =   isUS ?"." :",";
      format.thousands = isUS ?"," :".";
    }(("" + (+(0.00).toLocaleString()).toFixed(2)).indexOf(".") > 0));

    我用输入进行了测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    [  ""
      ,"1"
      ,"12"
      ,"123"
      ,"1234"
      ,"12345"
      ,"123456"
      ,"1234567"
      ,"12345678"
      ,"123456789"
      ,"1234567890"
      ,".12"
      ,"1.12"
      ,"12.12"
      ,"123.12"
      ,"1234.12"
      ,"12345.12"
      ,"123456.12"
      ,"1234567.12"
      ,"12345678.12"
      ,"123456789.12"
      ,"1234567890.12"
      ,"1234567890.123"
      ,"1234567890.125"
    ].forEach(function (item) {
      console.log(format(item));
    });

    得到这些结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    0.00
    1.00
    12.00
    123.00
    1,234.00
    12,345.00
    123,456.00
    1,234,567.00
    12,345,678.00
    123,456,789.00
    1,234,567,890.00
    0.12
    1.12
    12.12
    123.12
    1,234.12
    12,345.12
    123,456.12
    1,234,567.12
    12,345,678.12
    123,456,789.12
    1,234,567,890.12
    1,234,567,890.12
    1,234,567,890.13

    只是为了好玩。


    我想要一个普通的javascript解决方案,自动返回小数部分。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function formatDollar(amount) {
        var dollar = Number(amount).toLocaleString("us","currency");
        //decimals
        var arrAmount = dollar.split(".");
        if (arrAmount.length==2) {
            var decimal = arrAmount[1];
            if (decimal.length==1) {
                arrAmount[1] +="0";
            }
        }
        if (arrAmount.length==1) {
            arrAmount.push("00");
        }

        return"$" + arrAmount.join(".");
    }


    console.log(formatDollar("1812.2");

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    String.prototype.toPrice = function () {
        var v;
        if (/^\d+(,\d+)$/.test(this))
            v = this.replace(/,/, '.');
        else if (/^\d+((,\d{3})*(\.\d+)?)?$/.test(this))
            v = this.replace(/,/g,"");
        else if (/^\d+((.\d{3})*(,\d+)?)?$/.test(this))
            v = this.replace(/\./g,"").replace(/,/,".");
        var x = parseFloat(v).toFixed(2).toString().split("."),
        x1 = x[0],
        x2 = ((x.length == 2) ?"." + x[1] :".00"),
        exp = /^([0-9]+)(\d{3})/;
        while (exp.test(x1))
            x1 = x1.replace(exp,"$1" +"," +"$2");
        return x1 + x2;
    }

    alert("123123".toPrice()); //123,123.00
    alert("123123,316".toPrice()); //123,123.32
    alert("12,312,313.33213".toPrice()); //12,312,313.33
    alert("123.312.321,32132".toPrice()); //123,312,321.32

    我喜欢Vision最短的答案,除非我需要修改一个没有小数点的数字($123而不是$123.00),它不起作用,所以我需要破译javascript regex的晦涩语法,而不是快速复制/粘贴。

    这是最初的解决方案

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

    我会让它长一点:

    1
    2
    3
    var re = /\d(?=(\d{3})+\.)/g;
    var subst = '$&,';
    n.toFixed(2).replace(re, subst);

    此处的Re部分(字符串替换中的搜索部分)表示

  • 查找所有数字(\d)
  • 接着是(?=…)(展望未来)
  • 一组或多组()+
  • 精确到3位数(\d{3})
  • 以点结尾(\.)
  • 对所有事件都这样做(g)
  • 这里的Subst部分是指

  • 每次有匹配时,用它本身($&)替换它,后面跟一个逗号。
  • 当我们使用string.replace时,字符串中的所有其他文本保持不变,只有找到的数字(后面跟着3、6、9等其他数字)才能得到一个额外的逗号。

    所以在数字1234567.89中,数字1和4满足条件(1234567.89),并替换为"1"和"4",得到1234567.89。

    如果我们根本不需要美元金额的小数点(即123美元而不是123美元),我们可以这样更改regex:

    1
    var re2 = /\d(?=(\d{3})+$)/g;

    它依赖于行尾($)而不是点(\.),最后的表达式是(也要注意toFixed(0)):

    1
    n.toFixed(0).replace(/\d(?=(\d{3})+$)/g, '$&,');

    这个表达式将给出

    1
    1234567.89 -> 1,234,567

    另外,在上面的regex中,您也可以选择单词边界(\b,而不是行尾($)。

    如果我误解了Regex处理的任何部分,请提前道歉。


    我很难找到一个简单的库来处理日期和货币,所以我创建了我的:https://github.com/dericeira/slimformatter.js

    简单的是:

    1
    var number = slimFormatter.currency(2000.54);

    上面帕特里克流行答案的咖啡描述:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Number::formatMoney = (decimalPlaces, decimalChar, thousandsChar) ->  
      n = this  
      c = decimalPlaces  
      d = decimalChar  
      t = thousandsChar  
      c = (if isNaN(c = Math.abs(c)) then 2 else c)  
      d = (if d is undefined then"." else d)  
      t = (if t is undefined then"," else t)  
      s = (if n < 0 then"-" else"")  
      i = parseInt(n = Math.abs(+n or 0).toFixed(c)) +""  
      j = (if (j = i.length) > 3 then j % 3 else 0)  
      s + (if j then i.substr(0, j) + t else"") + i.substr(j).replace(/(\d{3})(?=\d)/g,"$1" + t) + (if c then d + Math.abs(n - i).toFixed(c).slice(2) else"")

    许多答案都有有益的想法,但没有一个能满足我的需要。所以我运用了所有的想法并建立了这个例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    function Format_Numb( fmt){
        var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
        if(typeof decSgn==="undefined") decSgn =".";
        if(typeof kommaSgn==="undefined") kommaSgn=",";

        var s3digits=/(\d{1,3}(?=(\d{3})+(?=[.]|$))|(?:[.]\d*))/g;
        var dflt_nk="00000000".substring(0,decimals);

        //--------------------------------
        // handler for pattern:"%m"
        var _f_money= function( v_in){
                    var v=v_in.toFixed(decimals);
                    var add_nk=",00";
                    var arr=    v.split(".");
                    return     arr[0].toString().replace(s3digits, function ($0) {
                                        return ($0.charAt(0)==".")
                                            ? ((add_nk=""),(kommaSgn + $0.substring(1)))
                                            : ($0 + decSgn);
                            })
                            + (    (decimals > 0)
                                    ?    (    kommaSgn
                                            + (
                                                (arr.length > 1)
                                                ? arr[1]
                                                : dflt_nk
                                            )
                                        )
                                    :   ""                    
                            );
        }

        // handler for pattern:"%<len>[.[cc lang="javascript"]]f"
        var _f_flt= function( v_in,l,prec){
            var v=(typeof prec !=="undefined") ? v_in.toFixed(prec):v_in;
            return ((typeof l !=="undefined")&&( (l=l-v.length) > 0))
                    ?(Array(l+1).join("") + v)
                    :v;
        }

        // handler for pattern:"%<len>x"
        var _f_hex= function( v_in,l,flUpper){
            var v=    Math.round(v_in).toString(16);
            if(flUpper)    v=v.toUpperCase();
            return ((typeof l !=="undefined")&&( (l=l-v.length) > 0))
                    ?(Array(l+1).join("0") + v)
                    :v;        
        }

        //...can be extended..., just add the function, f.e.:    var _f_octal= function( v_in,...){
        //--------------------------------

        if( typeof(fmt)!=="undefined"){
            //...can be extended..., just add the char,f.e."O":    MFX -> MFXO
            var rpatt=/(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
            var _qu=   """;
            var _mask_qu=   "
    \\"";
            var str=    fmt.toString().replace( rpatt,function($0,$1,$2,$3,$4){
                                    var f;
                                    if(typeof $1 !=="undefined"){
                                        switch($2.toUpperCase()){
                                            case"M":    f="_f_money(v)";    break;
                                            case"F":    var    n_dig0,n_dig1;
                                                    var    re_flt=/^(?:(\d))*(?:[.](\d))*$/;
                                                    $1.replace(re_flt,function($0,$1,$2){
                                                        n_dig0=$1;
                                                        n_dig1=$2;
                                                    });
                                                    f="_f_flt(v," + n_dig0 +"," + n_dig1 +")";    break;
                                            case"X":    var    n_dig="undefined";
                                                    var    re_flt=/^(\d*)$/;
                                                    $1.replace(re_flt,function($0){
                                                        if($0!="")n_dig=$0;
                                                    });
                                                    f="_f_hex(v," + n_dig +"," + ($2=="X") +")";    break;
                                            //...can be extended..., f.e.:    case"O":
                                        }
                                        return""+"+f+"+"";
                                    } else if(typeof $3 !=="undefined"){
                                        return _mask_qu + $3 + _mask_qu;
                                    } else {
                                        return ($4==_qu)?_mask_qu:$4.charAt(0);
                                    }
                                });
            var cmd=       "return function(v){"
                    +       "if(typeof v === "undefined")return "";"    //null returned as empty string
                    +       "if(!v.toFixed)return v.toString();"        //not numb returned as string
                    +       "return "" + str +"";"
                    +   "}";

            //...can be extended..., just add the function name in the 2 places:
            return new Function("_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
        }
    }

    首先,我需要一个C样式的格式字符串定义,它应该是灵活的,但非常容易使用,我用以下方式定义了它:模式:

    1
    2
    3
    4
    %[<len>][.[cc lang="javascript"]]f        float, example"%f","%8.2d","%.3f"
    %m                        money
    %[<len>]x                 hexadecimal lower case, example"%x","%8x"
    %[<len>]X                 hexadecimal upper case, example"%X","%8X"

    因为没有必要为我将其他格式设置为欧元,所以我只实现了"%m"。但很容易扩展…和C中一样,格式字符串是包含模式的字符串,对于欧元:"%M欧元"(返回字符串如"8.129,33欧元")。

    除了灵活性之外,我还需要一个非常快速的处理表的解决方案。这意味着,在处理数千个单元格时,格式字符串的处理不能超过一次。我不接受类似"格式(值,fmt)"的调用,但必须分为两个步骤:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // var formatter = Format_Numb("%m €");  
    //simple example for Euro...

    //   but we use a complex example:

    var formatter = Format_Numb("a%%%3mxx "zz"%8.2f°"  >0x%8X<");

    // formatter is now a function, which can be used more than once (this is an example, that can be tested:)

    var v1= formatter( 1897654.8198344);

    var v2= formatter( 4.2);

    ... (and thousands of rows)

    此外,为了提高性能,还将regexp封装在货币中;

    第三,不接受类似"格式(值,fmt)"的调用,因为:虽然应该可以用不同的掩码格式化不同的对象集合(即列的单元格),但我不想在处理点处理格式字符串。此时,我只想使用格式,比如

    for( var cell in cells){ do_something( cell.col.formatter(
    cell.value)); }

    什么格式-可能是在in i、每列的XML或其他某个地方定义的,但是分析和设置格式或处理国际化完全是在另一个地方处理的,在那里我想在不考虑性能问题的情况下将格式化程序分配给集合:

    col.formatter = Format_Numb( _getFormatForColumn(...) );

    第四,我需要一个"宽容"的解决方案,所以传递F.E.字符串而不是数字应该只返回字符串,但"空"应该返回空字符串。

    (如果值太大,格式化"%4.2f"也不能剪切某些内容。)

    最后但并非最不重要的一点——它应该可读且易于扩展,而不会对性能产生任何影响……例如,如果有人需要"八进制值",请参考带有"…可以扩展…"的行-我认为这应该是一个非常简单的任务。

    我的主要精力放在表现上。每个"处理例程"(f.e.u money)都可以在这个线程或其他线程中封装优化或与其他想法交换,而不需要更改"准备例程"(分析格式字符串和创建函数),这些例程必须只处理一次,从这个意义上讲,并不像数千个nu的转换调用那样性能关键。梅伯斯

    对于所有喜欢数字方法的人:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Number.prototype.format_euro=( function(formatter){
        return function(){ return formatter(this); }})
        (Format_Numb("%m €"));

    var v_euro= (8192.3282).format_euro(); //results: 8.192,33 €

    Number.prototype.format_hex= (function(formatter){
        return function(){ return formatter(this); }})
        (Format_Numb("%4x"));

    var v_hex= (4.3282).format_hex();

    虽然我测试了一些东西,但代码中可能有很多错误。所以这不是一个现成的模块,只是一个想法和一个像我这样的非JS专家的起点。代码中包含了大量stackoverflow文章中的许多和一些修改过的想法;抱歉,我不能引用所有这些想法,但要感谢所有专家。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function getMoney(A){
        var a = new Number(A);
        var b = a.toFixed(2); //get 12345678.90
        a = parseInt(a); // get 12345678
        b = (b-a).toPrecision(2); //get 0.90
        b = parseFloat(b).toFixed(2); //in case we get 0.0, we pad it out to 0.00
        a = a.toLocaleString();//put in commas - IE also puts in .00, so we'll get 12,345,678.00
        //if IE (our number ends in .00)
        if(a < 1 && a.lastIndexOf('.00') == (a.length - 3))
        {
            a=a.substr(0, a.length-3); //delete the .00
        }
        return a+b.substr(1);//remove the 0 from b, then return a + b = 12,345,678.90
    }
    alert(getMoney(12345678.9));

    这在FF和IE中有效


    已经有了很好的答案。以下是简单的娱乐尝试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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(',');  
    }

    运行一些示例

    1
    2
    3
    4
    5
    6
    7
    8
    console.log(
      currencyFormat(1),
      currencyFormat(1200),
      currencyFormat(123),
      currencyFormat(9870000),
      currencyFormat(12345),
      currencyFormat(123456.232)
    )

    下面是一个简单的格式设置工具,在Vanilla JS中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function numberFormatter (num) {
            console.log(num)
        var wholeAndDecimal = String(num.toFixed(2)).split(".");
        console.log(wholeAndDecimal)
        var reversedWholeNumber = Array.from(wholeAndDecimal[0]).reverse();
        var formattedOutput = [];

        reversedWholeNumber.forEach( (digit, index) => {
            formattedOutput.push(digit);
            if ((index + 1) % 3 === 0 && index < reversedWholeNumber.length - 1) {
                formattedOutput.push(",");
            }
        })

        formattedOutput = formattedOutput.reverse().join('') +"." + wholeAndDecimal[1];

        return formattedOutput;

    }

    我喜欢简单:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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("");
    }

    我想为此作出贡献:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function toMoney(amount) {
        neg = amount.charAt(0);
        amount= amount.replace(/\D/g, '');
        amount= amount.replace(/\./g  , '');
        amount= amount.replace(/\-/g, '');

        var numAmount = new Number(amount);
        amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
            return i > 0 && c !=="," && (a.length - i) % 3 === 0 ?"." + c : c;
        });

        if(neg == '-')
            return neg+amount;
        else
            return amount;
    }

    这允许您在一个文本框中转换数字,在该文本框中,您只需要supose来放置数字(考虑此方案)。

    这将清除一个文本框,其中只包含数字,即使您粘贴一个包含数字、字母或任何字符的字符串。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    <html>
    <head>
    <script language=="Javascript">
    function isNumber(evt) {    
        var theEvent = evt || window.event;
        var key = theEvent.keyCode || theEvent.which;
        key = String.fromCharCode(key);
        if (key.length == 0) return;
        var regex = /^[0-9\-\b]+$/;
        if (!regex.test(key)) {
            theEvent.returnValue = false;
            if (theEvent.preventDefault) theEvent.preventDefault();
        }
    }
    function toMoney(amount) {
        neg = amount.charAt(0);
        amount= amount.replace(/\D/g, '');
        amount= amount.replace(/\./g  , '');
        amount= amount.replace(/\-/g, '');

        var numAmount = new Number(amount);
        amount= numAmount .toFixed(0).replace(/./g, function(c, i, a) {
            return i > 0 && c !=="," && (a.length - i) % 3 === 0 ?"." + c : c;
        });

        if(neg == '-')
            return neg+amount;
        else
            return amount;
    }
    function clearText(inTxt, newTxt, outTxt) {
        inTxt = inTxt.trim();
        newTxt = newTxt.trim();
        if(inTxt == '' || inTxt == newTxt)
            return outTxt;

        return inTxt;  
    }

    function fillText(inTxt, outTxt) {
        inTxt = inTxt.trim();
        if(inTxt != '')
            outTxt = inTxt;

        return outTxt;
    }

    </head>
    <body>
    $ <input name=reca2 id=reca2 type=text value="0" onFocus="this.value = clearText(this.value, '0', '');" onblur="this.value = fillText(this.value, '0'); this.value = toMoney(this.value);" onKeyPress="isNumber(event);" style="width:80px;" />
    </body>
    </html>

    这是我的…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function thousandCommas(num) {
      num = num.toString().split('.');
      var ints = num[0].split('').reverse();
      for (var out=[],len=ints.length,i=0; i < len; i++) {
        if (i > 0 && (i % 3) === 0) out.push(',');
        out.push(ints[i]);
      }
      out = out.reverse() && out.join('');
      if (num.length === 2) out += '.' + num[1];
      return out;
    }

    因为每个问题都需要一线解决方案:

    1
    Number.prototype.formatCurrency = function() { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1,') : t + '.' + c; }, '$'); }

    对于不同的区域设置,这很容易更改,只需将"$1"更改为"$1."和".to"、"to"、"to swap"和。在数字中,货币符号可以通过更改末尾的"$"来更改。

    或者,如果您有ES6,您可以用默认值声明函数:

    1
    2
    3
    4
    5
    6
    7
    8
    Number.prototype.formatCurrency = function(thou = ',', dec = '.', sym = '$') { return this.toFixed(2).toString().split(/[-.]/).reverse().reduceRight(function (t, c, i) { return (i == 2) ? '-' + t : (i == 1) ? t + c.replace(/(\d)(?=(\d{3})+$)/g, '$1' + thou) : t + dec + c; }, sym); }

    console.log((4215.57).formatCurrency())
    $4,215.57
    console.log((4216635.57).formatCurrency('.', ','))
    $4.216.635,57
    console.log((4216635.57).formatCurrency('.', ',',"\u20AC"))
    €4.216.635,57

    哦,它也适用于负数:

    1
    2
    3
    4
    console.log((-6635.574).formatCurrency('.', ',',"\u20AC"))
    -6.635,57
    console.log((-1066.507).formatCurrency())
    -$1,066.51

    当然,你不必有货币符号

    1
    2
    3
    4
    5
    6
    console.log((1234.586).formatCurrency(',','.',''))
    1,234.59
    console.log((-7890123.456).formatCurrency(',','.',''))
    -7,890,123.46
    console.log((1237890.456).formatCurrency('.',',',''))
    1.237.890,46

    下面是使用regexp和replace的快速方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function formatCurrency( number, dp, ts ) {
      var num = parseFloat( number ); //convert to float
      var pw; //for IE
      dp = parseInt( dp, 10 ); //decimal point
      dp = isNaN( dp ) ? 2 : dp; //default 2 decimal point
      ts = ts || ','; //thousands separator

      return num != number ?
        false : //return false for NaN
        ( ( 0.9 ).toFixed( 0 ) == '1' ? //for cater IE toFixed bug
            num.toFixed( dp ) : //format to fix n decimal point with round up
            ( Math.round( num * ( pw = Math.pow( 10, dp ) || 1 ) ) / pw ).toFixed( dp ) //for fix ie toFixed bug on round up value like 0.9 in toFixed
        ).replace( /^(-?\d{1,3})((\d{3})*)(\.\d+)?$/, function( all, first, subsequence, dmp, dec ) { //separate string into different parts
          return ( first || '' ) + subsequence.replace( /(\d{3})/g, ts + '$1' ) + ( dec || '' ); //add thousands seperator and re-join all parts
        } );
    }