¿Cómo formatear números como cadena de moneda?

1848

Me gustaría formatear un precio en JavaScript. Me gustaría una función que tome a floatcomo argumento y devuelva un stringformato como este:

"$ 2,500.00"

¿Cuál es la mejor manera de hacer esto?

Daniel Magliola
fuente
8
No hay una función integrada formatNumberen javascript
zerkms
500
Por favor, para cualquiera que lea esto en el futuro, no use flotante para almacenar moneda. Perderá precisión y datos. Debe almacenarlo como un número entero de centavos (o centavos, etc.) y luego convertirlo antes de la salida.
Philip Whitehouse
8
@ user1308743 Float no almacena decimales. Almacena números usando un valor, base y desplazamiento. 0.01 no es realmente representable. Ver: en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Philip Whitehouse
66
@ user1308743: Imagine que representa un número muy grande (digamos que es un tipo con suerte y es el saldo de su cuenta bancaria). ¿Realmente querría perder dinero debido a una deficiencia de precisión?
antes del
163
Entonces, ¿por qué nadie ha sugerido lo siguiente? (2500) .toLocaleString ("en-GB", {estilo: "moneda", moneda: "GBP", mínimo dígitos de fracción: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nick Grealy

Respuestas:

1793

Number.prototype.toFixed

Esta solución es compatible con todos los principales navegadores:

  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)

Todo lo que necesita es agregar el símbolo de la moneda (por ejemplo "$" + profits.toFixed(2)) y tendrá su cantidad en dólares.

Función personalizada

Si requiere el uso de ,entre cada dígito, puede usar esta función:

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>

Úselo así:

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

Si siempre vas a usar '.' y ',', puede dejarlos fuera de su llamada al método, y el método los predeterminará por usted.

(123456789.12345).formatMoney(2);

Si su cultura tiene los dos símbolos invertidos (es decir, europeos) y desea utilizar los valores predeterminados, simplemente pegue las siguientes dos líneas en el formatMoneymétodo:

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

Función personalizada (ES6)

Si puede usar la sintaxis moderna de ECMAScript (es decir, a través de Babel), puede usar esta función más simple:

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
fuente
26
En primer lugar, excelente, código conciso. sin embargo, si usted es estadounidense, debe cambiar los valores predeterminados de dy tser .y ,respectivamente para que no tenga que especificarlos cada vez. Además, recomiendo modificar el comienzo de la returndeclaración para que lea: de lo return s + '$' + [rest]contrario no obtendrá un signo de dólar.
Jason
744
No estoy seguro de por qué la gente piensa que este código es hermoso. Es indescifrable. Parece funcionar bien, pero no es hermoso.
usr
86
¿Se ha copiado esta función formatMoney de algún código JavaScript minificado en alguna parte? ¿No puedes publicar el original? ¿Qué significan las variables c, d, i, j, n, s y t? A juzgar por la cantidad de votos a favor y comentarios que tiene esta publicación, puedo suponer que este código se ha copiado y pegado en sitios web de producción en todas partes ... ¡Buena suerte manteniendo el código si algún día tiene un error!
zuallauz
259
"poesía"? Más como la oscuridad. Esto no es golf de código; usa un pequeño espacio en blanco. Los nombres de var adecuados tampoco harían daño.
keithjgrant
1516

Formato numérico internacional

Javascript tiene un formateador de números (parte de la API de internacionalización).

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

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

Violín JS

Use undefineden lugar del primer argumento ( 'en-US'en el ejemplo) para usar la configuración regional del sistema (la configuración regional del usuario en caso de que el código se ejecute en un navegador). Explicación adicional del código local .

Aquí hay una lista de los códigos de moneda .

Intl.NumberFormat vs Number.prototype.toLocaleString

Una nota final que compara esto con la anterior. toLocaleString. Ambos ofrecen esencialmente la misma funcionalidad. Sin embargo, toLocaleString en sus encarnaciones anteriores (pre-Intl) en realidad no admite configuraciones regionales : utiliza la configuración regional del sistema. Por lo tanto, asegúrese de estar utilizando la versión correcta ( MDN sugiere verificar la existencia deIntl ). Además, el rendimiento de ambos es el mismo para un solo elemento, pero si tiene muchos números para formatear, el uso Intl.NumberFormates ~ 70 veces más rápido. Aquí se explica cómo usarlo toLocaleString:

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

Algunas notas sobre el soporte del navegador

  • El soporte del navegador ya no es un problema hoy en día, con un 97.5% de soporte global, 98% en los EE. UU. Y 99% en la UE
  • Hay una cuña para en navegadores fosilizados (como IE8), en caso de que realmente necesite
  • Echa un vistazo a CanIUse para más información
aross
fuente
89
Esta solución idomática de JavaScript, simple y elegante, es exactamente lo que estaba buscando.
Guilhem Soulas
99
Votar esta porque es una respuesta estúpidamente simple que funciona de forma nativa.
Trasiva
17
Es bastante seguro que un porcentaje bastante alto de navegadores ahora lo admiten. Esto debería ser votado mucho más.
flq
2
Esta es una gran respuesta y la tengo trabajando con un valor de moneda dinámico, por lo que si el uso está en Europa, cambia a EUR y muestra el símbolo del euro. Funciona una delicia!
Sprose
3
Es 2018 y esto es básicamente compatible en todas partes. Esta debería ser la respuesta correcta.
sarink
1340

Solución corta y rápida (¡funciona en todas partes!)

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

La idea detrás de esta solución es reemplazar las secciones coincidentes con la primera coincidencia y la coma, es decir '$&,' . La coincidencia se realiza mediante el enfoque de búsqueda anticipada . Puede leer la expresión como "hacer coincidir un número si es seguido por una secuencia de tres conjuntos de números (uno o más) y un punto" .

PRUEBAS

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"

MANIFESTACIÓN: http://jsfiddle.net/hAfMM/9571/


Solución corta extendida

También puede extender el prototipo de Numberobjeto para agregar soporte adicional de cualquier número de decimales [0 .. n]y el tamaño de los 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 / PRUEBAS: http://jsfiddle.net/hAfMM/435/


Solución corta super extendida

En esta versión súper extendida , puede establecer 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 / PRUEBAS: http://jsfiddle.net/hAfMM/612/

VisioN
fuente
21
De hecho, me dio un paso más: .replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,").
kalisjoshua
44
Versión CoffeeScript con expresiones regulares de VisioN y kalisjoshua y forma de especificar el lugar decimal (para que pueda dejar el valor predeterminado de 2 o especificar 0 para ningún decimal):Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
Eric Anderson
11
@Abbas Sí, reemplace \.con $(final de línea), es decir this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,").
VisioN
2
@hanumant La gramática regular es un poco complicada aquí, así que le sugiero que lea primero los manuales sobre expresiones regulares (por ejemplo, en MDN ). La idea detrás de esto es reemplazar las secciones coincidentes con el primer partido y la coma, es decir $1,. La correspondencia se realiza utilizando el enfoque de búsqueda anticipada . Puede leer la expresión como "hacer coincidir un número si es seguido por una secuencia de tres conjuntos de números (uno o más) y un punto" .
VisioN
2
@ JuliendePrabère Por favor, dé un ejemplo de un número largo que no funciona con este enfoque.
VisioN
248

Eche un vistazo al objeto Número JavaScript y vea si puede ayudarlo.

  • toLocaleString() formateará un número usando un separador de miles específico de ubicación.
  • toFixed() redondeará el número a un número específico de lugares decimales.

Para usarlos al mismo tiempo, el valor debe cambiar su tipo a un número porque ambos generan una cadena.

Ejemplo:

Number((someNumber).toFixed(1)).toLocaleString()
17 de 26
fuente
2
¡Gracias! ¡De acuerdo con esta idea, pude hacer uno que sea lo suficientemente corto y simple! (y localizado) Excelente.
Daniel Magliola
77
En realidad puedes. es decir, para dólares: '$' + (valor + 0.001) .toLocaleString (). slice (0, -1)
Zaptree
66
Parece que sería genial, pero hay poca compatibilidad con el navegador en este momento
acorncom
1
@acorncom ¿Por qué dice que hay "poca compatibilidad con el navegador"? El objeto Number ha existido desde Javascript 1.1. Proporcione una referencia que respalde su reclamo.
Doug S
2
Se debe tener cuidado de que haya una versión anterior toLocaleStringque use la configuración regional del sistema y una nueva (incompatible) que provenga de la API ECMAScript Intl. Explicado aquí . Esta respuesta parece estar destinada a la versión anterior.
aross
162

A continuación se muestra el código de Patrick Desjardins (alias Daok) con un poco de comentarios agregados y algunos cambios menores:

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

y aquí algunas pruebas:

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

Los cambios menores son:

  1. movido un poco Math.abs(decimals)para que se haga solo cuando no es así NaN.

  2. decimal_sep ya no puede ser una cadena vacía (un tipo de separador decimal es imprescindible)

  3. usamos typeof thousands_sep === 'undefined'como se sugiere en Cómo determinar mejor si un argumento no se envía a la función JavaScript

  4. (+n || 0)no es necesario porque thises un Numberobjeto

JS Fiddle

Marco Demaio
fuente
8
Es posible que desee utilizar '10' como la raíz en parseInt. De lo contrario, cualquier número que comience con '0' usará la numeración octal.
sohtimsso1970
3
@ sohtimsso1970: perdón por la respuesta tardía, pero ¿podría explicar algo más? No veo dónde un número podría interpretarse como octal. Se parseIntllama al valor absoluto de la parte INTEGER del número. ¡La parte INTEGER no puede comenzar con CERO a menos que sea solo CERO! Y parseInt(0) === 0octal o decimal.
Marco Demaio
pruebe, por ejemplo: parseInt ("016") ... devuelve 14, ya que parseInt supone que está codificado en octal, cuando la cadena comienza con un cero.
Rastreador1
44
@ Tracker1: Comprendí que un número que comienza con 0es considerado octal por parseInt. Pero en este código es IMPOSIBLE parseIntrecibir 016como entrada (o cualquier otro valor con formato octal), porque el argumento pasado parseIntes procesado primero por la Math.absfunción. Por lo tanto, no hay forma de parseIntrecibir un número que comience con cero a menos que sea solo un cero o 0.nn(donde nnestán los decimales). Pero ambos 0y las 0.nncadenas se convertirían parseInten un CERO simple como se supone que es.
Marco Demaio
Esta función es incorrecta:> (2030) .toMoney (0, '.', ''); <"2 03 0"
Anton P Robul
124

contabilidad.js es una pequeña biblioteca de JavaScript para el formato de números, dinero y divisas.

GasheK
fuente
... solo recuerde pasar un símbolo de moneda; de lo contrario, se producirá un error en IE7 e IE8, IE9 está bien de cualquier manera
vector
2
Parece que el error IE7 / IE8 está solucionado.
Mat Schaffer
2
Esta es una gran biblioteca, poder pasar el símbolo de la moneda también es una buena idea, ya que todos los detalles de la moneda están contenidos en la llamada / configuración de función única
farinspace
2
Me gusta el hecho de que puede hacer lo contrario: pasar una cadena de moneda formateada y obtener el valor numérico.
Neil Monroe
2
contabilidad.js no parece mantenerse últimamente. Una bifurcación con cambios recientes es github.com/nashdot/accounting-js
RationalDev le gusta GoFundMonica el
124

Si la cantidad es un número, digamos -123, entonces

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

producirá la cuerda "-$123.00" .

Aquí hay un ejemplo de trabajo completo .

cs01
fuente
77
Esta respuesta estaba casi ahí para mí, pero necesitaba redondearla al centavo más cercano. Esto es lo que usé amount.toLocaleString ('en-GB', {style: 'currency', currency: 'GBP', maximumFractionDigits: 2});
Nico
El código anterior se redondea al número de dígitos que desea. Vea el ejemplo y escriba 1.237 en el cuadro de entrada.
Daniel Barbalace
3
No parece funcionar en Safari. Simplemente devuelve el número como una cadena sin ningún formato.
Lance Anderson
1
Wow, esta es una gran respuesta. Debería ser superior.
Ethan
2
Si por alguna razón no quiere centavos, puede cambiar la precisión decimal con:minimumFractionDigits: 0
Horacio
99

Aquí está el mejor formateador de dinero js que he visto:

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

Fue reformateado y prestado desde aquí: https://stackoverflow.com/a/149099/751484

Tendrá que suministrar su propio designador de moneda (usó $ arriba).

Llámelo de esta manera (aunque tenga en cuenta que los argumentos predeterminados son 2, coma y punto, por lo que no necesita proporcionar ningún argumento si es su preferencia):

var myMoney=3543.75873;
var formattedMoney = '$' + myMoney.formatMoney(2,',','.'); // "$3,543.76"
Jonathan M
fuente
cuidado con el signo
global
66
@hacklikecrack, todas las variables son locales; Están en la vardeclaración.
Jonathan M
3
lo siento, sí, aunque estás redefiniendo argumentos. ¡Sangría! ;)
hacklikecrack
¡Uso horrible de nombres de variables!
Serj Sagan
77

Ya hay algunas respuestas geniales aquí. Aquí hay otro intento, solo por diversión:

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

Y algunas pruebas:

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: ahora también manejará números negativos

Wayne Burkett
fuente
poesía. brillante. ¿Has probado reduceRight () developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… que debería eliminar el reverse ()?
Steve
1
@ Steve - Tienes razón, pero necesitarías hacer algo como i = orig.length - i - 1en la devolución de llamada. Aún así, uno menos transversal de la matriz.
Wayne
11
No se trata de compatibilidad: el reducemétodo se introdujo en Ecmascript 1.8 y no es compatible con Internet Explorer 8 y versiones posteriores.
Blaise
Como dijo @Blaise, este método no funcionará en IE 8 o inferior.
rsbarro
Sí, por supuesto que es correcto. Como se señaló en la respuesta en sí, esto es solo por diversión. Además, debe manejar números negativos muy bien.
Wayne
76

Funciona para todos los navegadores actuales

Úselo toLocaleStringpara formatear una moneda en su representación sensible al idioma (usando los códigos de moneda ISO 4217 ).

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

Fragmentos de código de Rand sudafricano de ejemplo 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
fuente
1
Debido a que los argumentos 'locales' y 'opciones' son compatibles solo con un número muy pequeño de navegadores, como Chrome 24, IE11 y Opera 15. Firefox, Safari y las versiones anteriores de otros aún no lo admiten.
VisioN
3
De acuerdo, todavía no es totalmente compatible con todos los navegadores, pero sigue siendo una solución. (Y podría decirse que la solución más válida, ya que es compatible con los navegadores no compatibles, y es una característica documentada de la API de Javascript.)
Nick Grealy
1
Me gusta esto y estoy feliz de que funcione con la agrupación de dígitos de la India.
MSC
77
Esto es totalmente compatible a partir de 2017 y debería ser la única respuesta correcta
Evgeny
1
Último y mejor :) FF69, Chrome76, etc. "R 2 500,00" no es lo que usamos aquí, debería ser "R 2,500.00", igual que en-GB.
avenmore
70

Creo que lo que quieres es f.nettotal.value = "$" + showValue.toFixed(2);

Persona especial
fuente
@ aplastar esto funciona pero ya no lleva los cálculos al campo de impuestos?
Rocco The Taco
11
Una vez que le agrega un signo $, ya no es un número, sino una cadena.
aplastar
Esta opción no pone una coma entre los miles. :-(
Simon East
29

Numeral.js : una biblioteca js para formatear fácilmente los números por @adamwdraper

numeral(23456.789).format('$0,0.00'); // = "$23,456.79"
Yarin
fuente
El tenedor Numbro parece recibir más amor cuando Numeral.js parece abandonado: github.com/foretagsplatsen/numbro
RationalDev le gusta GoFundMonica el
Numeral.js está activo nuevamente.
adamwdraper
27

Ok, basado en lo que dijiste, estoy usando esto:

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;

Estoy abierto a sugerencias de mejora (preferiría no incluir YUI solo para hacer esto :-)) Ya sé que debería detectar el "." en lugar de solo usarlo como separador decimal ...

Daniel Magliola
fuente
8
Tenga en cuenta que su versión no se redondea correctamente a dos dígitos decimales. Por ejemplo, 3.706 se formateará como "£ 3.70", no como "£ 3.71" como se supone que debe ser.
Ates Goral
Sí, eso está bien en mi caso particular, ya que las cantidades con las que estoy trabajando ya tienen como máximo 2 dígitos. La razón por la que necesito fijar 2 decimales es para cantidades sin decimales o con solo 1.
Daniel Magliola
26

Yo uso la biblioteca Globalizar (de Microsoft):

¡Es un gran proyecto para localizar números, monedas y fechas y tenerlos formateados automáticamente de la manera correcta de acuerdo con la configuración regional del usuario! ... y a pesar de que debería ser una extensión jQuery, actualmente es una biblioteca 100% independiente. ¡Les sugiero a todos que lo prueben! :)

daveoncode
fuente
3
Wow, ¿por qué no se vota más? Gran biblioteca estandarizada para todo tipo de formato. Parámetros de formato estándar de la industria con correcta globalización. ¡¡Gran respuesta!!
pbarranis
Todavía se considera etapa alfa, así que úsalo con precaución, pero es un gran hallazgo.
Neil Monroe
1
Ya no en alfa (o beta). Esto parece ser muy útil mientras esperamos que Safari cumpla con el nuevo estándar y que IE <11 muera.
Guy Schalnat
25

javascript-number-formatter (anteriormente en Google Code )

  • Corto, rápido, flexible pero independiente. Solo 75 líneas incluyendo información de licencia MIT, líneas en blanco y comentarios.
  • Aceptar formato de número estándar como #,##0.00 o con negación -000.####.
  • Aceptar cualquier formato de país como # ##0,00, #,###.##, #'###.##o cualquier tipo de símbolo no de numeración.
  • Acepte cualquier número de agrupación de dígitos. #,##,#0.000o #,###0.##son todos válidos
  • Acepte cualquier formateo redundante / infalible. ##,###,##.#o 0#,#00#.###0#están todos bien.
  • Redondeo automático de números.
  • Interfaz sencilla, simplemente máscara de suministro y valor de la siguiente manera: format( "0.0000", 3.141592).
  • Incluye un prefijo y sufijo con la máscara

(extracto de su archivo README)

Goodeq
fuente
23

+1 a Jonathan M por proporcionar el método original. Dado que esto es explícitamente un formateador de moneda, seguí adelante y agregué el símbolo de moneda (predeterminado a '$') a la salida, y agregué una coma predeterminada como el separador de miles. Si realmente no desea un símbolo de moneda (o separador de miles), simplemente use "" (cadena vacía) como argumento para ello.

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
fuente
La primera var es un poco extraña, ya que esas variables ya están declaradas en la declaración de función. Aparte de eso, gracias!
Rich Bradshaw
2
Tienes razón. Ese es un error que traje del original de Jonathan M, donde todos están encadenados como una sola expresión var. Esas deberían ser tareas simples. Fijación.
XML
Para el caso, creo que esto probablemente se optimiza prematuramente y debería ser refactorizado para facilitar su lectura. Pero mi objetivo era aumentar el código del OP, no alterarlo fundamentalmente.
XML
No está tan mal, +n || 0es lo único que me parece un poco extraño (de todos modos, para mí).
Rich Bradshaw
2
thises un nombre de variable perfectamente útil. Convertirlo para nque pueda guardar 3 caracteres en el momento de la definición puede haber sido necesario en una era en la que se contaban RAM y ancho de banda en KB, pero es simplemente ofuscatorio en una era en la que el minificador se ocupará de todo eso antes de que llegue a producción. Las otras micro optimizaciones inteligentes son al menos discutibles.
XML
22

Hay un puerto javascript de la función PHP "number_format".

Lo encuentro muy útil, ya que es fácil de usar y reconocible para los desarrolladores 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; 
}

(Bloque de comentarios del original , incluido a continuación para ejemplos y crédito cuando sea debido)

// 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
fuente
Esta es solo una función correcta:> number_format (2030, 0, '.', '') <'2 030' ¡Genial! Gracias
Anton P Robul
21

¿Un método más corto (para insertar espacio, coma o punto) con expresión regular?

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

    n=12345678.9;
    alert(n.toCurrencyString());
revs Julien de Prabère
fuente
20

No he visto nada como esto. Es bastante conciso y 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)
)

Aquí hay una versión con más opciones en la salida final para permitir formatear diferentes monedas en diferentes formatos de localidad.

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

sintetizadas
fuente
Gran fragmento de código, gracias. Sin embargo, tenga cuidado, ya que no funcionará en IE porque los parámetros predeterminados no son compatibles, y "const" y "let" no son compatibles en <IE11. Ue esto para arreglar: + moneyFormat: function (price, sign) {+ if (! Sign) sign = '$'; + piezas = parseFloat (precio) .toFixed (2) .split ('') + var ii = pieces.length - 3
Charlie Dalsass
No te preocupes @CharlieDalsass. Recomendaría usar babel para compilarlo en ES5 para el código de producción.
Synthet1c
Pero, ¿cómo hacer moneda euro? 1.000,00 euros?
@YumYumYum Agregué un ejemplo completo con más opciones de formato para permitir una mayor flexibilidad.
Synthet1c
18

La respuesta de Patrick Desjardins se ve bien, pero prefiero que mi javascript sea simple. Aquí hay una función que acabo de escribir para tomar un número y devolverlo en formato de moneda (menos el signo de dólar)

// 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
fuente
Necesitaba algo para trabajar tanto en el navegador como en una versión anterior de Node. Esto funcionó perfectamente. Gracias
n8jadams
17

La parte principal es insertar los miles de separadores, que podrían hacerse así:

<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
fuente
Me sale un número incorrecto al ingresar valores negativos a ins1000Sep ().
Peter
16

Hay un incorporado en function Fijo enjavascript

var num = new Number(349);
document.write("$" + num.toFixed(2));
portón
fuente
Esta respuesta parece redundante. La respuesta de Crush ya se mencionótoFixed()
Ian Dunn
3
toFixed()es una función del Numberobjeto y no funcionará var numsi fuera un String, por lo que el contexto adicional me ayudó.
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 el lagarto
fuente
Pequeño y simple. Gracias.
Connor Simpson
1
simple, pero sin coma por 1,000
aron
15

Sugiero la clase NumberFormat de la API de visualización de Google .

Puedes hacer algo como esto:

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

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

Espero que ayude.

juanchopx2
fuente
14

Esto puede ser un poco tarde, pero aquí hay un método que acabo de elaborar para que un compañero de trabajo agregue una función de reconocimiento local .toCurrencyString()a todos los números. La internalización es solo para la agrupación de números, NO el signo de la moneda; si está generando dólares, úselos "$"como se suministran, porque $123 4567en Japón o China es la misma cantidad de USD que $1,234,567aquí en los EE. UU. Si está emitiendo euro / etc., cambie el signo de moneda de"$" .

Declare esto en cualquier lugar de su CABEZA o donde sea necesario, justo antes de que necesite usarlo:

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

¡Entonces has terminado! Úselo en (number).toCurrencyString()cualquier lugar donde necesite generar el número como moneda.

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

Como de costumbre, hay varias formas de hacer lo mismo, pero evitaría usarlo, Number.prototype.toLocaleStringya que puede devolver diferentes valores en función de la configuración del usuario.

Tampoco recomiendo extender los Number.prototype- prototipos de objetos nativos extendidos es una mala práctica ya que puede causar conflictos con el código de otras personas (por ejemplo, bibliotecas / frameworks / complementos) y puede no ser compatible con futuras implementaciones / versiones de JavaScript.

Creo que las expresiones regulares son el mejor enfoque para el problema, aquí está mi implementación:

/**
 * 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 el 30/08/2010: opción agregada para establecer el número de dígitos decimales. editado el 23/08/2011: opción agregada para establecer el número de dígitos decimales a cero.

Miller Medeiros
fuente
El punto de toLocaleString es que se ajusta con la configuración del usuario.
Joseph Lennox
11

Aquí hay algunas soluciones, todas pasan el conjunto de pruebas, el conjunto de pruebas y el punto de referencia incluido, si desea copiar y pegar para probar, pruebe This Gist .

Método 0 (RegExp)

Base en https://stackoverflow.com/a/14428340/1877620 , pero corrija si no hay un punto 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 en 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 (bucle)

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

Ejemplo 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

Si queremos separador de miles personalizado o separador decimal, use replace():

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

Banco de pruebas

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

Punto de referencia

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();
Steely Wing
fuente
Mejorado de su método 2. cambie de var a = this.toFixed (precision) .split ('.'), A var multiplier = Math.pow (10, precision + 1), wholeNumber = Math.floor (this * multiplier) ; var a = Math.round (enteroNúmero / 10) * 10 / multiplicador; if (Cadena (a) .indexOf ('.') <1) {a + = '.00'; } a = Cadena (a) .split ('.'), No use toFixed porque tiene errores.
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 todos estos valores decimales deben ser .84 no .83
vee
11

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

Adam Pery
fuente
10

Una opción simple para la colocación adecuada de la coma invirtiendo la cadena primero y la expresión regular 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
fuente
10

Encontré esto en: contabilidad.js . Es muy fácil y se adapta perfectamente a mis necesidades.

// 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
fuente
$('#price').val( accounting.formatMoney(OOA, { symbol: "€", precision: 2,thousand: ".", decimal :",",format: "%v%s" } ) );- mostrar 1.000,00 E