Como formatar números como string de moeda?

1846

Gostaria de formatar um preço em JavaScript. Eu gostaria de uma função que leva a floatcomo argumento e retorna um stringformatado como este:

"$ 2,500.00"

Qual é a melhor forma de fazer isso?

Daniel Magliola
fonte
8
Não há nenhuma função embutida formatNumberno javascript
zerkms
500
Por favor, para quem ler isso no futuro, não use float para armazenar moeda. Você perderá precisão e dados. Você deve armazená-lo como um número inteiro de centavos (ou centavos etc.) e depois converter antes da saída.
Philip Whitehouse
8
@ user1308743 O flutuador não armazena casas decimais. Ele armazena números usando um valor, base e deslocamento. 0,01 não é realmente representável. Veja: en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Philip Whitehouse
6
@ user1308743: Imagine que você representa um número muito grande (digamos que você seja um sortudo e esse é o saldo da sua conta bancária). Você realmente gostaria de perder dinheiro por causa de uma deficiência de precisão?
ereOn
163
Então, por que ninguém sugeriu o seguinte? (2500) .toLocaleString ("pt-BR", {estilo: "moeda", moeda: "GBP", minimumFractionDigits: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nick Grealy

Respostas:

1792

Number.prototype.toFixed

Esta solução é compatível com todos os principais navegadores principais:

  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)

Tudo que você precisa é adicionar o símbolo da moeda (por exemplo "$" + profits.toFixed(2)) e você terá seu valor em dólares.

Função personalizada

Se você precisar usar ,entre cada dígito, poderá usar esta função:

function formatMoney(number, decPlaces, decSep, thouSep) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSep = typeof decSep === "undefined" ? "." : decSep;
thouSep = typeof thouSep === "undefined" ? "," : thouSep;
var sign = number < 0 ? "-" : "";
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));
var j = (j = i.length) > 3 ? j % 3 : 0;

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

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

Use-o assim:

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

Se você sempre usará '.' e ',', você pode excluí-los da chamada de método, e o método os padronizará para você.

(123456789.12345).formatMoney(2);

Se sua cultura possui os dois símbolos invertidos (europeus) e você deseja usar os padrões, cole as duas linhas a seguir no formatMoneymétodo:

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

Função personalizada (ES6)

Se você pode usar a sintaxe moderna do ECMAScript (por exemplo, através do Babel), pode usar esta função mais simples:

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

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

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

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

haykam
fonte
26
primeiro de tudo, um código excelente e conciso. no entanto, se você é americano, deve alterar os padrões de de tpara .e e, ,respectivamente, para não precisar especificá-los sempre. Além disso, eu recomendo modificar o início da returndeclaração para ler return s + '$' + [rest]:, caso contrário você não receberá um cifrão.
Jason
744
Não sei por que as pessoas acham esse código bonito. É indecifrável. Parece funcionar bem, mas não é bonito.
usr
86
Essa função formatMoney é copiada de algum código JavaScript minificado em algum lugar? Você não pode postar o original? O que significam as variáveis ​​c, d, i, j, n, se et? A julgar pela quantidade de votos e comentários deste post, posso assumir que esse código foi copiado e colado em sites de produção em todos os lugares ... Boa sorte em manter o código se houver algum erro algum dia!
Zuallauz
259
"poesia"? Mais como obscuridade. Isso não é código de golfe; use um pouco de espaço em branco. Nomes de var adequados também não machucariam.
keithjgrant
1515

Intl.numberformat

Javascript tem um formatador de números (parte da API de internacionalização).

// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

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

JS violino

Use undefinedno lugar do primeiro argumento ( 'en-US'no exemplo) para usar a localidade do sistema (a localidade do usuário, caso o código esteja sendo executado em um navegador). Mais explicações sobre o código de localidade .

Aqui está uma lista dos códigos de moeda .

Intl.NumberFormat vs Number.prototype.toLocaleString

Uma nota final comparando isso com o anterior. toLocaleString. Ambos oferecem essencialmente a mesma funcionalidade. No entanto, toLocaleString em suas encarnações mais antigas (pré-Intl) na verdade não suporta localidades : ele usa a localidade do sistema. Portanto, verifique se você está usando a versão correta (o MDN sugere verificar a existência deIntl ). Além disso, o desempenho de ambos é o mesmo para um único item, mas se você tiver muitos números para formatar, o uso Intl.NumberFormatserá aproximadamente 70 vezes mais rápido. Aqui está como usar toLocaleString:

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

Algumas notas sobre o suporte ao navegador

  • Atualmente, o suporte a navegadores não é mais um problema, com 97,5% de suporte global, 98% nos EUA e 99% na UE.
  • Existe um calço para suportá-lo em navegadores fossilizados (como o IE8), caso você realmente precise
  • Dê uma olhada no CanIUse para obter mais informações
aross
fonte
89
Esta solução idomatic JavaScript, simples e elegante é exatamente o que eu estava procurando.
Guilhem Soulas
9
Votar este porque é uma resposta estupidamente simples que funciona de forma nativa.
Trasiva 30/08/16
17
Certamente, uma porcentagem bastante alta de navegadores agora suporta isso. Isso deve ser votado muito mais.
FLQ
2
Esta é uma ótima resposta e eu tenho que trabalhar com um valor dinâmico da moeda. Se o uso for na Europa, ele muda para EUR e mostra o sinal do euro. Funciona um prazer!
Sprose
3
É 2018 e isso é basicamente suportado em todos os lugares. Essa deve ser a resposta correta.
sarink
1340

Solução curta e rápida (funciona em qualquer lugar!)

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

A idéia por trás dessa solução é substituir 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 "corresponder a um número se for seguida por uma sequência de três conjuntos de números (um ou mais) e um ponto" .

ENSAIOS:

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 de Numberobjeto para adicionar suporte adicional a qualquer número de casas decimais [0 .. n]e ao 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"

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

DEMO / TESTES: http://jsfiddle.net/hAfMM/612/

VisioN
fonte
21
Eu realmente foi um passo além: .replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,").
precisa saber é o seguinte
4
Versão CoffeeScript com de visão & regexp kalisjoshua e maneira de especificar casa decimal (assim você pode deixar o padrão de 2 ou especificar 0 para não decimal):Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
Eric Anderson
11
@ Abbas Sim, substitua \.por $(fim de linha), ie this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,").
VisioN
2
@hanumant A gramática regular é um pouco complicada aqui, por isso sugiro que você leia primeiro os manuais sobre expressões regulares (por exemplo, na MDN ). A idéia por trás disso é substituir as seções correspondentes pela primeira correspondência e vírgula, ou seja $1,. A correspondência é feita usando a abordagem lookahead . Você pode ler a expressão como "corresponder a um número se for seguida por uma sequência de três conjuntos de números (um ou mais) e um ponto" .
VisioN
2
@ JuliendePrabère Por favor, dê um exemplo de um número longo que não funciona com essa abordagem.
VisioN
248

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

  • toLocaleString() formatará um número usando o separador de milhares específico do local.
  • toFixed() 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 produzem uma sequência.

Exemplo:

Number((someNumber).toFixed(1)).toLocaleString()
17 de 26
fonte
2
Obrigado! Com base nessa idéia, consegui criar uma que seja curta e simples o suficiente! (e localizado) Excelente.
Daniel Magliola 29/09/08
7
Na verdade você pode. ou seja, para dólares: '$' + (valor + 0,001) .toLocaleString (). slice (0, -1)
Zaptree
6
Parece que seria ótimo, mas há pouco apoio navegador no momento
acorncom
1
@acorncom Por que você diz que há "pouco suporte ao navegador"? O objeto Number existe desde o Javascript 1.1. Forneça uma referência que faça backup de sua reivindicação.
Doug S
2
Deve-se tomar cuidado para que exista uma versão antiga toLocaleStringque use o código do idioma do sistema e uma nova (incompatível) proveniente da API ECMAScript Intl. Explicado aqui . Esta resposta parece ser destinada à versão antiga.
aross 14/09/17
162

Abaixo está o código de Patrick Desjardins (também conhecido como 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 [/programming/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. mudou um pouco a Math.abs(decimals)ser feito apenas quando não é NaN.

  2. decimal_sep não pode mais ser uma string vazia (um tipo de separador decimal é obrigatório)

  3. usamos typeof thousands_sep === 'undefined'como sugerido em Qual a melhor forma de determinar se um argumento não é enviado para a função JavaScript

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

JS Fiddle

Marco Demaio
fonte
8
Você pode querer usar '10' como a raiz em parseInt. Caso contrário, qualquer número que comece com '0' usará a numeração octal.
sohtimsso1970
3
@ sohtimsso1970: desculpe pela resposta tardia, mas você poderia explicar um pouco mais? Não vejo onde um número pode ser interpretado como octal. A parseIntchama-se sobre o valor absoluto da parte inteira do número. A parte INTEGER não pode começar com ZERO, a menos que seja apenas um ZERO! E parseInt(0) === 0octal ou decimal.
Marco Demaio 9/02/12
tente, por exemplo: parseInt ("016") ... retorna 14, pois parseInt assume que é codificado octal, quando a sequência começa com um zero.
precisa
4
@ Tracker1: Entendi que um número começando com 0é considerado octal por parseInt. Mas neste código é IMPOSSÍVEL parseIntreceber 016como entrada (ou qualquer outro valor formatado octal), porque o argumento passado parseInté o primeiro processado pela Math.absfunção. Portanto, não há como parseIntreceber um número que começa com zero, a menos que seja apenas zero ou 0.nn(onde nnsão decimais). Mas ambos 0e 0.nnstrings seriam convertidos parseIntem um ZERO simples, como deveria ser.
Marco Demaio 20/03/12
Esta função está incorreta:> (2030) .toMoney (0, '.', ''); <"2 03 0"
Anton P Robul 18/03/16
124

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

GasheK
fonte
... lembre-se de passar um símbolo de moeda, caso contrário, ele erros no IE7 e IE8, o IE9 é bom de qualquer maneira
vector
2
Parece que o bug do IE7 / IE8 foi corrigido.
Mat Schaffer
2
Esta é uma grande biblioteca, sendo capaz de passar o símbolo da moeda é também uma boa ideia, uma vez que todos os detalhes de moeda estão contidos na única chamada de função / configurações
farinspace
2
Gosto do fato de que você pode fazer o inverso - passar uma string de moeda formatada e obter o valor numérico.
Neil Monroe
2
accounting.js não parece ser mantido ultimamente. Um garfo com mudanças recentes é github.com/nashdot/accounting-js
RationalDev gosta GoFundMonica
124

Se quantidade é 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 .

cs01
fonte
7
Essa resposta estava quase lá para mim, mas eu precisava que ela fosse arredondada para o centavo mais próximo. Foi isso que usei amount.toLocaleString ('en-GB', {style: 'currency', moeda: 'GBP', maximumFractionDigits: 2});
Nico
O código acima faz o arredondamento para o número de dígitos que você deseja. Veja o exemplo e digite 1.237 na caixa de entrada.
Daniel Barbalace
3
Não parece funcionar no Safari. Apenas retorna o número como uma String sem formatação.
Lance Anderson
1
Uau, esta é realmente uma ótima resposta. Deve estar no topo.
Ethan
2
Se, por algum motivo, você não quiser centavos, poderá alterar a precisão decimal com:minimumFractionDigits: 0
Horacio
99

Aqui está o melhor formatador js money 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 reformatado e emprestado a partir daqui: https://stackoverflow.com/a/149099/751484

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

Chame assim (embora observe que os argumentos padrão são 2, vírgula e ponto; portanto, você não precisa fornecer argumentos, se essa for a sua preferência):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
Jonathan M
fonte
atente para globals sinal, i, j
hacklikecrack
6
@hacklikecrack, todas as variáveis ​​são locais; eles estão na vardeclaração.
Jonathan M
3
desculpe, sim, embora você esteja denunciando argumentos. Recuo! ;)
hacklikecrack 25/02
Uso horrível de nomes de variáveis!
Serj Sagan
77

Já existem ó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 também manipula números negativos

Wayne Burkett
fonte
poesia. brilhante. você já tentou reduzirRight () developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… que deveria eliminar o reverse ()?
Steve
1
@ Steve - Você está certo, mas precisaria fazer algo como i = orig.length - i - 1no retorno de chamada. Ainda assim, menos uma travessia da matriz.
Wayne
11
Não se trata de compatibilidade: o reducemétodo foi introduzido no Ecmascript 1.8 e não é suportado no Internet Explorer 8 e abaixo.
Blaise
Como o @Blaise disse, esse método não funcionará no IE 8 ou abaixo.
Rsbarro
Sim, claro que está correto. Como observado na própria resposta, isso é apenas por diversão. Além disso, ele deve lidar com números negativos muito bem.
Wayne
76

Funciona para todos os navegadores atuais

Use toLocaleStringpara formatar uma moeda em sua representação sensível ao idioma (usando códigos de moeda ISO 4217 ).

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

Exemplo de trechos de código Rand sul-africano para @avenmore

console.log((2500).toLocaleString("en-ZA", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> R 2 500,00
console.log((2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2}))
// -> ZAR 2,500.00

Nick Grealy
fonte
1
Como os argumentos 'locales' e 'options' são suportados apenas por um número muito pequeno de navegadores, como Chrome 24, IE11 e Opera 15. Firefox, Safari e versões mais antigas de outros ainda não o suportam.
VisioN
3
Concordado, ainda não é totalmente compatível com todos os navegadores, mas ainda é uma solução. (E, sem dúvida, a solução mais válida, como a sua frente compatível com os navegadores não suportados, e é uma característica documentada da API Javascript.)
Nick Grealy
1
Eu gosto disso e estou feliz que ele funciona com o agrupamento de dígitos indianos.
MSC
7
Isso é totalmente suportado a partir de 2017 e deve ser a única resposta correta
Evgeny
1
Mais recentes e melhores :) FF69, Chrome76, etc. "R 2 500,00" não é o que usamos aqui, deve ser "R 2.500,00", o mesmo que en-GB.
precisa saber é
70

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

A paixão súbita
fonte
@ esmagar isso funciona, mas não carrega mais os cálculos no campo de imposto?
Rocco The Taco
11
Depois de anexar um sinal $, ele não é mais um número, mas uma sequência.
esmagar
Esta opção não coloca uma vírgula entre os milhares. :-(
Simon East
29

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"
Yarin
fonte
O garfo Numbro parece ficar mais amor como Numeral.js parece abandonada: github.com/foretagsplatsen/numbro
RationalDev gosta GoFundMonica
O Numeral.js está ativo novamente.
precisa saber é o seguinte
27

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 melhorias (eu preferiria não incluir a YUI apenas para fazer isso :-)) Eu já sei que deveria estar detectando o "." em vez de apenas usá-lo como separador decimal ...

Daniel Magliola
fonte
8
Observe que sua versão não arredonda corretamente para dois dígitos decimais. Por exemplo, 3,706 seria formatado como "£ 3,70", não como "£ 3,71" como deveria.
Ates Goral 30/09/08
Sim, tudo bem no meu caso em particular, uma vez que os valores com os quais trabalho já têm no máximo 2 dígitos. O motivo pelo qual preciso corrigir com 2 decimais é para valores sem decimais ou apenas com 1.
Daniel Magliola
26

Eu uso a biblioteca Globalize (da Microsoft):

É um ótimo projeto localizar números, moedas e datas e formatá-los automaticamente da maneira certa, 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 que experimentem! :)

daveoncode
fonte
3
Uau, por que isso não é mais votado? Grande biblioteca padronizada para todos os tipos de formatação. Parâmetros de formatação padrão do setor com globalização correta. Ótima resposta!!
Pbarranis
Ainda é considerado estágio alfa, portanto, use com cautela, mas ótimo achado.
Neil Monroe
1
Não está mais em alfa (ou beta). Isso parece ser muito útil enquanto esperamos que o Safari atenda ao novo padrão e que o IE <11 morra.
precisa saber é o seguinte
25

formatador de número javascript (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 a formatação de número padrão como #,##0.00ou com negação -000.####.
  • Aceitar qualquer formato país como # ##0,00, #,###.##,#'###.## ou qualquer tipo de símbolo não-numeração.
  • Aceite qualquer número de agrupamento de dígitos. #,##,#0.000ou #,###0.##são todos válidos.
  • Aceite qualquer formatação redundante / infalível. ##,###,##.#ou 0#,#00#.###0#estão todos bem.
  • Arredondamento automático de número.
  • Interface simples, basta fornecer máscara e valor como este: format( "0.0000", 3.141592) .
  • Inclua um prefixo e sufixo na máscara

(trecho do seu README)

Goodeq
fonte
23

+1 a Jonathan M por fornecer o método original. Como este é explicitamente um formatador de moeda, fui adiante e adicionei o símbolo da moeda (o padrão é '$') à saída e adicionei uma vírgula padrão como separador de milhares. Se você realmente não deseja um símbolo de moeda (ou separador de milhares), basta usar "" (sequência vazia) como 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) : "");
};
XML
fonte
A primeira var é meio estranha, pois essas variáveis ​​já estão declaradas na declaração da função. Fora isso, obrigado!
Ricos Bradshaw
2
Você está certo. Esse é um erro que eu trouxe do original de Jonathan M, onde todos estão encadeados como uma única expressão var. Essas devem ser tarefas simples. Fixação.
XML
A propósito, acho que isso provavelmente é prematuramente otimizado e deve ser refatorado para facilitar a leitura. Mas meu objetivo era aumentar o código do OP, não alterá-lo fundamentalmente.
XML
Não é tão ruim - +n || 0é a única coisa que parece um pouco estranha (para mim de qualquer maneira).
Ricos Bradshaw
2
thisé um nome de variável perfeitamente útil. Convertê-lo para nsalvar três caracteres no momento da definição pode ter sido necessário em uma época em que a RAM e a largura de banda eram contadas em KB, mas é simplesmente ofuscante em uma época em que o minifier cuidará de tudo isso antes de atingir a produção. As outras micro otimizações inteligentes são pelo menos discutíveis.
XML
22

Existe uma porta javascript da função PHP "number_format".

Acho muito útil, pois é fácil de usar e reconhecível pelos desenvolvedores de 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'
DaMayan
fonte
Esta é apenas uma função correta:> number_format (2030, 0, '.', '') <'2 030' Ótimo! Graças
Anton P Robul
21

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());
Julien de Prabère
fonte
20

Não vi nada assim. É bem conciso e fácil de entender.

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

Aqui está uma versão com mais opções na saída final para permitir a formatação de diferentes moedas em diferentes formatos de localidade.

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

synthet1c
fonte
Ótimo trecho de código, obrigado. No entanto, tenha cuidado, pois ele não funcionará no IE porque os parâmetros padrão não são suportados e "const" e "let" não são suportados no <IE11. Use isto para corrigir: + moneyFormat: function (preço, sinal) {+ if (! Sinal) sign = '$'; + pieces = parseFloat (price) .toFixed (2) .split ('') + var ii = pieces.length - 3
Charlie Dalsass
Não se preocupe @CharlieDalsass. Eu recomendaria usar o babel para compilá-lo no ES5 para código de produção.
synthet1c
Mas como fazer moeda euro? 1.000,00 Euros?
@YumYumYum Adicionei um exemplo completo com mais opções de formatação para permitir mais flexibilidade.
synthet1c
18

A resposta de Patrick Desjardins parece boa, mas eu prefiro meu javascript simples. Aqui está uma função que acabei de escrever para pegar um número e devolvê-lo no 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];
}
Tim Saylor
fonte
Eu precisava de algo para trabalhar no navegador e em uma versão antiga do Node. Isso funcionou perfeitamente. Graças
n8jadams
17

A parte principal é inserir os mil separadores, que poderiam ser feitos assim:

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

<button onclick="alert(ins1000Sep(formatNum(12313231)));">
roenving
fonte
Recebo um número errado de saída ao inserir valores negativos para ins1000Sep ().
Peter
16

Há um built-in function toFixed emjavascript

var num = new Number(349);
document.write("$" + num.toFixed(2));
Portão
fonte
Essa resposta parece redundante. A resposta do Crush já está mentidatoFixed()
Ian Dunn
3
toFixed()é uma função do Numberobjeto e não funcionará var numse for um String, portanto o contexto adicional me ajudou.
timborden
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;
}

De WillMaster .

Bill the Lizard
fonte
Pequeno e simples. Obrigado.
Connor Simpson
1
simples, mas nenhuma vírgula para 1.000
Aron
15

Sugiro a classe NumberFormat da API de visualização do Google .

Você pode fazer algo assim:

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

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

Espero que ajude.

juanchopx2
fonte
14

Pode ser um pouco tarde, mas aqui está um método que acabei de criar para um colega de trabalho para adicionar uma .toCurrencyString()função com reconhecimento de localidade a todos os números. A internalização é apenas para agrupamento de números, NÃO para o sinal de moeda - se você estiver produzindo dólares, use "$"como fornecido, porque $123 4567no Japão ou na China é o mesmo número de dólares que $1,234,567aqui nos EUA. Se você estiver produzindo euro / etc., Altere o sinal de moeda de"$" .

Declare isso em qualquer lugar do seu HEAD ou sempre que necessário, antes de precisar usá-lo:

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

Então você está pronto! Use em (number).toCurrencyString()qualquer lugar que você precise exibir o número como moeda.

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

Como geralmente, existem várias maneiras de fazer a mesma coisa, mas eu evitaria usá- Number.prototype.toLocaleStringlo, pois ele pode retornar valores diferentes com base nas configurações do usuário.

Também não recomendo estender o Number.prototypeprotótipo de objetos nativos é uma prática ruim, pois pode causar conflitos com o código de outras pessoas (por exemplo, bibliotecas / estruturas / plugins) e pode não ser compatível com futuras implementações / versões de JavaScript.

Acredito que expressões regulares são a melhor abordagem para o problema, aqui está a minha implementação:

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

editado em 30/08/2010: opção adicionada para definir o número de dígitos decimais. editado em 23/08/2011: opção adicionada para definir o número de dígitos decimais como zero.

Miller Medeiros
fonte
O ponto de toLocaleString é que ele se ajusta às configurações do usuário.
Joseph Lennox
11

Aqui estão algumas soluções: todas passam no conjunto de testes, no conjunto de testes e no benchmark incluídos. Se você deseja copiar e colar para testar, tente This Gist .

Método 0 (RegExp)

Baseie-se em https://stackoverflow.com/a/14428340/1877620 , mas corrija se não houver ponto decimal.

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

Método 2 (Dividir em matriz)

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

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

Exemplo de uso

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

Separador

Se quisermos separador de milhares personalizado ou separador decimal, use replace():

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

Suíte de teste

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();
Asa de Aço
fonte
Aprimorado do seu método 2. mude de var a = this.toFixed (precision) .split ('.'), Para var multiplicador = Math.pow (10, precision + 1), wholeNumber = Math.floor (this * multiplicator) ; var a = Math.round (número inteiro / 10) * 10 / multiplicador; if (String (a) .indexOf ('.') <1) {a + = '.00'; } a = String (a) .split ('.'), não use toFixed porque é um bug.
vee
console.log (parseFloat ('4.835'). toFixed (2)); > 4.83 console.log (parseFloat ('54 .835 '). ToFixed (2)); > 54.84 console.log (parseFloat ('454.835'). ToFixed (2)); > 454.83 console.log (parseFloat ('8454.835'). ToFixed (2)); > 8454,83 todo o valor decimal desse valor deve ser 0,84 e não 0,83
vee
11

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

Adam Pery
fonte
10

Uma opção simples para o posicionamento correto da vírgula, revertendo a cadeia de caracteres primeiro e a regexp básica.

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();
};
troy
fonte
10

Encontrei isso em: accounting.js . É muito fácil e se encaixa perfeitamente na minha necessidade.

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

Faysal Haque
fonte
$('#price').val( accounting.formatMoney(OOA, { symbol: "€", precision: 2,thousand: ".", decimal :",",format: "%v%s" } ) );- mostrar 1.000,00 E