Como posso formatar números como string de moeda de dólares em JavaScript?

Eu gostaria de formatar um preço em JavaScript.
Eu gostaria de uma function que leva um float como um argumento e retorna uma string formatada como esta:

 "$ 2,500.00" 

Qual é a melhor forma de fazer isso?

Você pode usar:

  var profits=2489.8237 profits.toFixed(3) //returns 2489.824 (round up) profits.toFixed(2) //returns 2489.82 profits.toFixed(7) //returns 2489.8237000 (padding) 

Então você pode adicionar o sinal de ‘$’.

Se você precisar de ‘,’ por mil você pode usar:

 Number.prototype.formatMoney = function(c, d, t){ var n = this, 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) : ""); }; 

E use-o com:

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

Se você sempre vai usar ‘. e ‘,’, você pode deixá-los fora de sua chamada de método, e o método irá padronizá-los para você.

 (123456789.12345).formatMoney(2); 

Se a sua cultura tiver os dois símbolos invertidos (ou seja, europeus), basta colar as duas linhas seguintes no método formatMoney :

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

Solução rápida e curta (funciona em todos os lugares!)

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

A ideia por trás dessa solução é replace as seções correspondentes pela primeira correspondência e vírgula, ou seja, '$&,' . A correspondência é feita usando a abordagem lookahead . Você pode ler a expressão como “combinar um número, se for seguido por uma sequência de três conjuntos de números (um ou mais) e um ponto” .

TESTES:

 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" 

DEMO: http://jsfiddle.net/hAfMM/9571/


Solução curta estendida

Você também pode estender o protótipo do object Number para adicionar suporte adicional de qualquer número de decimais [0 .. n] e o tamanho dos grupos de números [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" 

DEMONSTRAÇÃO / TESTES: http://jsfiddle.net/hAfMM/435/


Solução curta super estendida

Nesta versão super estendida, você pode definir diferentes tipos de delimitadores:

 /** * 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" 

DEMONSTRAÇÃO / TESTES: http://jsfiddle.net/hAfMM/612/

Formato de numeração internacional

Javascript tem um formatador numérico (parte da API de Internacionalização).

 // 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 */ 

Violino JS

Algumas notas sobre suporte ao navegador

  • Todos os principais navegadores suportam hoje em dia
  • Os maiores ofensores em termos de suporte são o UC Mobile ( fique longe disso ) e o Opera Mini (prejudicado pelo design)
  • Há um shim para suportá-lo em navegadores mais antigos
  • Dê uma olhada no CanIUse para mais informações

Intl.NumberFormat vs Number.prototype.toLocaleString

Uma nota final comparando isso com o mais antigo. toLocaleString . Ambos oferecem essencialmente a mesma funcionalidade. No entanto, toLocaleString em suas encarnações anteriores (pré-Intl) não oferece suporte a localidades : ele usa a localidade do sistema. Portanto, para ter certeza de que você está usando a versão correta, o MDN sugere verificar a existência do Intl . Então, se você precisa verificar o Intl, por que não usá- lo ? No entanto, se você optar por usar o shim, isso também toLocaleString , então, nesse caso, você pode usá-lo sem qualquer aborrecimento:

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

Dê uma olhada no object JavaScript Number e veja se ele pode ajudá-lo.

  • toLocaleString() formatará um número usando o separador de milhares de local específico.
  • toFixed() irá arredondar o número para um número específico de casas decimais.

Para usá-los ao mesmo tempo, o valor deve ter seu tipo alterado de volta para um número, porque ambos emitem uma cadeia.

Exemplo:

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

Abaixo está o código de Patrick Desjardins (apelido Daok) com alguns comentários adicionados e algumas pequenas alterações:

 /* 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) : ''); } 

e aqui alguns testes:

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

As pequenas alterações são:

  1. moveu um pouco o Math.abs(decimals) para ser feito somente quando não é NaN .

  2. decimal_sep não pode mais ser string vazia (algum tipo de separador decimal é um MUST)

  3. nós usamos typeof thousands_sep === 'undefined' como sugerido em Como melhor determinar se um argumento não é enviado para a function JavaScript

  4. (+n || 0) não é necessário porque this é um object Number

O accounting.js é uma pequena biblioteca JavaScript para formatação de números, dinheiro e moeda.

Aqui está o melhor formatador de dinheiro js que eu já vi:

 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) : ""); }; 

Foi re-formatado e emprestado daqui: https://stackoverflow.com/a/149099/751484

Você terá que fornecer seu próprio designador de moeda (você usou $ acima).

Chamá-lo assim (embora note que os argumentos padrão para 2, vírgula, e período, então você não precisa fornecer quaisquer args se essa é sua preferência):

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

Se quantidade for um número, digamos -123 , então

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

irá produzir a string "-$123.00" .

Aqui está um exemplo completo de trabalho.

Já existem algumas ótimas respostas aqui. Aqui está outra tentativa, apenas por diversão:

 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]; } 

E alguns testes:

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

Editado: agora ele vai lidar com números negativos também

Eu acho que o que você quer é f.nettotal.value = "$" + showValue.toFixed(2);

Então, por que ninguém sugeriu o seguinte?

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

Funciona para a maioria / alguns navegadores:

https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Browser_Compatibility

Ok, com base no que você disse, eu estou usando isso:

 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; 

Estou aberto a sugestões de melhoria (prefiro não include YUI apenas para fazer isso :-)) Eu já sei que deveria estar detectando o “.” em vez de apenas usá-lo como separador decimal …

Eu uso a biblioteca Globalize (da Microsoft):

É um ótimo projeto para localizar números, moedas e datas e formatá-los automaticamente de acordo com a localidade do usuário! … e apesar de ser uma extensão do jQuery, atualmente é uma biblioteca 100% independente. Eu sugiro a todos vocês que experimentem! 🙂

Numeral.js – uma biblioteca js para facilitar a formatação de números por @adamwdraper

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

javascript-number-formatter (anteriormente no Google Code )

  • Curto, rápido, flexível e independente. Apenas 75 linhas, incluindo informações de licença do MIT, linhas em branco e comentários.
  • Aceite formatação numérica padrão como #,##0.00 ou com negação -000.#### .
  • Aceite qualquer formato de país como # ##0,00 , #,###.## , #'###.## ou qualquer tipo de símbolo de não numeração.
  • Aceite qualquer número de agrupamento de dígitos. #,##,#0.000 ou #,###0.## são todos válidos.
  • Aceite qualquer formatação redundante / à prova de erros. ##,###,##.# ou 0#,#00#.###0# estão todos OK.
  • Arredondamento automático de números.
  • Interface simples, basta fornecer máscara e valor como este: format( "0.0000", 3.141592) .
  • Inclua um prefixo e sufixo com a máscara

(trecho do seu README)

Existe uma porta javascript da function PHP “number_format”.

Eu acho muito útil, pois é fácil de usar e reconhecível para desenvolvedores PHP.

 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; } 

(Bloco de comentários do original , incluído abaixo para exemplos e crédito, quando devido)

 // 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 para Jonathan M por fornecer o método original. Como isso é explicitamente um formatador de moeda, fui em frente e adicionei o símbolo da moeda (o padrão é ‘$’) à saída e adicionei uma vírgula padrão como separador de milhar. Se você não quer realmente um símbolo de moeda (ou separador de milhares), apenas use “” (string vazia) como seu argumento para isso.

 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) : ""); }; 

Um método mais curto (para inserir espaço, vírgula ou ponto) com expressão regular?

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

Resposta Patrick Desjardins parece ser bom, mas eu prefiro o meu javascript simples. Aqui está uma function que acabei de escrever para pegar um número e devolvê-lo em formato de moeda (menos o cifrão)

 // 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]; } 

There is a built-in function toFixed in javascript

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

I suggest the NumberFormat class from Google Visualization API .

Você pode fazer algo assim:

 var formatter = new google.visualization.NumberFormat({ prefix: '$', pattern: '#,###,###.##' }); formatter.formatValue(1000000); // $ 1,000,000 

Espero que ajude.

Haven’t seen this one. It’s pretty concise and easy to understand.

 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) ) 
 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; } 

From WillMaster .

The main part is inserting the thousand-separators, that could be done like this:

   

This might be a little late, but here’s a method I just worked up for a coworker to add a locale-aware .toCurrencyString() function to all numbers. The internalization is for number grouping only, NOT the currency sign – if you’re outputting dollars, use "$" as supplied, because $123 4567 in Japan or China is the same number of USD as $1,234,567 is here in the US. If you’re outputting euro/etc., then change the currency sign from "$" .

Declare this anywhere in your HEAD or wherever necessary, just before you need to use it:

  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; } 

Then you’re done! Use (number).toCurrencyString() anywhere you need to output the number as currency.

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

As usually, there are multiple ways of doing the same thing but I would avoid using Number.prototype.toLocaleString since it can return different values based on the user settings.

I also don’t recommend extending the Number.prototype – extending native objects prototypes is a bad practice since it can cause conflicts with other people code (eg libraries/frameworks/plugins) and may not be compatible with future JavaScript implementations/versions.

I believe that Regular Expressions are the best approach for the problem, here is my implementation:

 /** * 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 (eg 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); } } 

edited on 2010/08/30: added option to set number of decimal digits. edited on 2011/08/23: added option to set number of decimal digits to zero.

Here are some solutions, all pass the test suite, test suite and benchmark included, if you want copy and paste to test, try This Gist .

Method 0 (RegExp)

Base on https://stackoverflow.com/a/14428340/1877620 , but fix if there is no decimal point.

 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('.'); } } 

Método 1

 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('.'); }; } 

Method 2 (Split to Array)

 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('.'); }; } 

Method 3 (Loop)

 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(''); }; } 

Usage Example

 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)); } 

Separator

If we want custom thousands separator or decimal separator, use replace() :

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

Test suite

 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); 

Referência

 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(); 

I found this from: accounting.js . Its very easy and perfectly fits my need.

 // 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€ 

A simple option for proper comma placement by reversing the string first and basic regexp.

 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 (ex Daok)’s example worked well for me. I ported over to coffeescript if anyone is interested.

 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 
    Intereting Posts