Cómo imprimir un número con comas como separadores de miles en JavaScript

2214

Estoy tratando de imprimir un número entero en JavaScript con comas como separadores de miles. Por ejemplo, quiero mostrar el número 1234567 como "1,234,567". ¿Cómo haría yo para hacer esto?

Así es como lo estoy haciendo:

function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

¿Existe una forma más sencilla o elegante de hacerlo? Sería bueno que también funcionara con flotadores, pero eso no es necesario. No es necesario que sea específico de la configuración regional para decidir entre puntos y comas.

12
  • 237
    Número (x) .toLocaleString ()
    Boffin
    9 de marzo de 2015 a las 23:04
  • 56
    Cabe destacar que Number.prototype.toLocaleString todavía no funciona en Safari, en 2016 . En lugar de formatear realmente el número, simplemente lo devuelve, no arroja ningún error. Tener la palma de la mano más grande hoy como resultado de eso ... #goodworkApple
    aendra
    10/0316 a las 11:21
  • 2
    @atomless ¿De verdad? Yo tengo Version 61.0.3163.100 (Official Build) (64-bit)y cuando digo (2982932323).toLocaleString()la respuesta es "2,982,932,323". Mi configuración regional predeterminada es en-US. Quizás deberías intentarlo (2982932323).toLocaleString('en-US'). 2 de noviembre de 2017 a las 2:46
  • 1
    Parece que esta debería ser la respuesta aprobada ... Intl.NumberFormat ('en-US'). Formato (recuento) Consulte developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 28/10/19 a las 23:19
  • 4
    Number.prototype.toLocaleString funciona en Safari 14, en 2021.
    Martijn
    21 abr a las 11:36
3396

Usé la idea de la respuesta de Kerry, pero la simplifiqué ya que solo estaba buscando algo simple para mi propósito específico. Aquí esta lo que hice:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
    return pass;
}

let failures = 0;
failures += !test(0,        "0");
failures += !test(100,      "100");
failures += !test(1000,     "1,000");
failures += !test(10000,    "10,000");
failures += !test(100000,   "100,000");
failures += !test(1000000,  "1,000,000");
failures += !test(10000000, "10,000,000");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

La expresión regular usa 2 aserciones de anticipación:

  • uno positivo para buscar cualquier punto en la cadena que tenga un múltiplo de 3 dígitos seguidos después,
  • una afirmación negativa para asegurarse de que el punto solo tenga exactamente un múltiplo de 3 dígitos. La expresión de reemplazo pone una coma allí.

Por ejemplo, si lo pasa 123456789.01, la afirmación positiva coincidirá con todos los puntos a la izquierda del 7 (ya que 789es un múltiplo de 3 dígitos, 678es un múltiplo de 3 dígitos 567, etc.). La afirmación negativa verifica que el múltiplo de 3 dígitos no tenga ningún dígito después. 789tiene un punto después, por lo que es exactamente un múltiplo de 3 dígitos, por lo que una coma va allí. 678es un múltiplo de 3 dígitos pero tiene un 9después, por lo que esos 3 dígitos son parte de un grupo de 4, y una coma no va allí. Del mismo modo para 567. 456789es de 6 dígitos, que es un múltiplo de 3, por lo que una coma va antes de eso. 345678es un múltiplo de 3, pero tiene un 9después, por lo que no hay coma allí. Etcétera. los\B evita que la expresión regular ponga una coma al principio de la cadena.

@ neu-rah mencionó que esta función agrega comas en lugares indeseables si hay más de 3 dígitos después del punto decimal. Si esto es un problema, puede utilizar esta función:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
    return pass;
}

let failures = 0;
failures += !test(0              , "0");
failures += !test(0.123456       , "0.123456");
failures += !test(100            , "100");
failures += !test(100.123456     , "100.123456");
failures += !test(1000           , "1,000");
failures += !test(1000.123456    , "1,000.123456");
failures += !test(10000          , "10,000");
failures += !test(10000.123456   , "10,000.123456");
failures += !test(100000         , "100,000");
failures += !test(100000.123456  , "100,000.123456");
failures += !test(1000000        , "1,000,000");
failures += !test(1000000.123456 , "1,000,000.123456");
failures += !test(10000000       , "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

@ tjcrowder señaló que ahora que JavaScript tiene lookbehind ( información de soporte ), se puede resolver en la propia expresión regular:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
    return pass;
}

let failures = 0;
failures += !test(0,               "0");
failures += !test(0.123456,        "0.123456");
failures += !test(100,             "100");
failures += !test(100.123456,      "100.123456");
failures += !test(1000,            "1,000");
failures += !test(1000.123456,     "1,000.123456");
failures += !test(10000,           "10,000");
failures += !test(10000.123456,    "10,000.123456");
failures += !test(100000,          "100,000");
failures += !test(100000.123456,   "100,000.123456");
failures += !test(1000000,         "1,000,000");
failures += !test(1000000.123456,  "1,000,000.123456");
failures += !test(10000000,        "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

(?<!\.\d*)es una búsqueda hacia atrás negativa que indica que la coincidencia no puede ir precedida de un número .seguido de cero o más dígitos. La búsqueda hacia atrás negativa es más rápida que la solución splity join( comparación ), al menos en V8.

43
  • 27
    Muy bueno, noté que tiene problemas con números que tienen más de 3 lugares después del punto decimal. 23/02/12 a las 18:34
  • 76
    prueba numberWithCommas (12345.6789) -> "12,345.6,789" no me gusta
    neu-rah
    27 de mayo de 2012 a las 13:28
  • 35
    Pequeña mejora que se soluciona después de '.' problema '123456789.01234'.replace (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g,' _ ') 17 de junio de 2013 a las 9:29
  • 10
    @DmitrijGolubev No funciona para enteros. Quizás forzar el punto decimal sería la solución.
    Vlad
    20/01/15 a las 16:13
  • 11
    Esto no funciona en safari. Rompí toda mi solicitud y me tomó una eternidad darme cuenta de que este era el problema 19/08/20 a las 5:19
2402

Me sorprende que nadie haya mencionado Number.prototype.toLocaleString . Está implementado en JavaScript 1.5 (que se introdujo en 1999), por lo que básicamente es compatible con todos los navegadores principales.

var n = 34523453.345
n.toLocaleString()
"34,523,453.345"

También funciona en Node.js a partir de v0.12 mediante la inclusión de Intl

Si quieres algo diferente, Numeral.js puede ser interesante.

23
  • 30
    @csigrist Buenos puntos, pero no es tan malo como parece. La velocidad depende del navegador. En FF u Opera funciona bien. Aunque apesta en Chrome. En cuanto a los ceros: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"sin embargo, esas opciones no funcionan en FF o Safari.
    uKolka
    23/07/2013 a las 15:50
  • 29
    La diferencia de rendimiento puede ser un problema o no, según el contexto. Si se usa para una tabla gigante de 1000 resultados, será más importante, pero si solo se usa para un valor único, la diferencia es insignificante. Pero la ventaja es que tiene en cuenta la configuración regional, por lo que alguien en Europa vería 34.523.453.345 o 34.523.453.345 . Esto sería más importante en un sitio con visitantes de muchos países. 12 feb 2014 a las 21:06
  • 9
    Impresionante. Finalmente una respuesta con función nativa. Y lo que es más, este se muestra correctamente en diferentes países con diferentes separadores (en República Checa escribimos X XXX XXX,YYY). 7 de julio de 2014 a las 17:02
  • 28
    Actualización para googlers: toLocaleStringfunciona en Node.js a partir de v0.12 mediante la inclusión de Intl . 2/11/15 a las 16:59
  • 15
    @MSC deberías probar parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})o en su new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})lugar. No funciona porque lo usas en una cadena, no en un número.
    uKolka
    22/02/2016 a las 16:29
388

A continuación, se muestran dos API de navegador diferentes que pueden transformar Numbers en cadenas estructuradas . Tenga en cuenta que no todas las máquinas de los usuarios tienen una configuración regional que usa comas en números . Para aplicar comas a la salida, se puede utilizar cualquier configuración regional "occidental" , comoen-US

var number = 1234567890; // Example number to be converted

⚠️ Tenga en cuenta que javascript tiene un valor entero máximo de9007199254740991


// default behaviour on a machine with a local that uses commas for numbers
number.toLocaleString(); // "1,234,567,890"

// With custom settings, forcing a "US" locale to guarantee commas in output
var number2 = 1234.56789; // floating point example
number2.toLocaleString('en-US', {maximumFractionDigits:2}) // "1,234.57"

Formato numérico

var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"

Por lo que verifiqué (Firefox al menos), ambos son más o menos iguales en cuanto al rendimiento.

Demostración en vivo : https://codepen.io/vsync/pen/MWjdbgL?editors=1000

10
  • 15
    NumberFormat no es compatible con Safari, para cualquiera que lo esté implementando allí. 12/11/15 a las 1:53
  • 12
    toLocaleString tampoco es compatible con safari 1 de febrero de 2016 a las 8:12
  • 5
    La compatibilidad con los navegadores siempre se menciona en la parte inferior de cada página de MDN, a la que he vinculado.
    vsync
    19 de marzo de 2016 a las 16:38
  • 5
    toLocaleStringtrabajos básicos en safari, las opciones no 21/06/2016 a las 9:16
  • 4
    la toLocaleStringsolución probablemente también debería incluir la configuración regional deseada, así que toLocaleString("en"), debido a que el patrón en inglés usa comas. Sin embargo, si toLocaleString()se ejecuta sin el indicador de configuración regional en Francia, entonces arrojará puntos en lugar de comas porque eso es lo que se usa para separar miles localmente. 17/11/2016 a las 18:05
120

Sugiero usar el number_format () de phpjs.org

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   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)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     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'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

ACTUALIZACIÓN 13/02/14

La gente ha estado informando que esto no funciona como se esperaba, así que hice un JS Fiddle que incluye pruebas automatizadas.

Actualización 26/11/2017

Aquí está ese violín como un fragmento de pila con una salida ligeramente modificada:

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   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)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     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'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

var exampleNumber = 1;
function test(expected, number, decimals, dec_point, thousands_sep)
{
    var actual = number_format(number, decimals, dec_point, thousands_sep);
    console.log(
        'Test case ' + exampleNumber + ': ' +
        '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
        ', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
        ', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
    );
    console.log('  => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
    exampleNumber++;
}

test('1,235',    1234.56);
test('1 234,56', 1234.56, 2, ',', ' ');
test('1234.57',  1234.5678, 2, '.', '');
test('67,00',    67, 2, ',', '.');
test('1,000',    1000);
test('67.31',    67.311, 2);
test('1,000.6',  1000.55, 1);
test('67.000,00000', 67000, 5, ',', '.');
test('1',        0.9, 0);
test('1.20',     '1.20', 2);
test('1.2000',   '1.20', 4);
test('1.200',    '1.2000', 3);
.as-console-wrapper {
  max-height: 100% !important;
}
9
  • 3
    @Andrew S: solo 1 persona lo ha marcado. Funciona, lo he usado en mi propio código muchas veces. Tampoco es mi código (ni mis pruebas), hice referencia al sitio de donde proviene, que es un sitio muy conocido. Quizás tengan una versión actualizada) ya que el código que está viendo tiene 3 años. 19 de junio de 2013 a las 18:03
  • 15
    @ernix: el operador solicitó JavaScript, esa respuesta que di es JavaScript. Esta es una interpretación de JavaScript de una función PHP. 23 de enero de 2014 a las 6:04
  • 2
    @ernix: funciona exactamente como se esperaba con el ejemplo que dio el OP. Pongo un violín para que lo veas. 13/0214 a las 17:12
  • 4
    @ernix - Está bien, pero el punto es que hace exactamente lo que pidió el OP. Es de otro sitio (no mantenido por mí, y lo he dicho anteriormente), y al darle las variables adecuadas, funciona exactamente como se indica. Si cree que eso es un error, comuníquese con phpjs.org o vea si tienen una versión actualizada. 13/0214 a las 20:06
  • 1
    Esto es perfecto. Seguí buscando y solo encontré bibliotecas increíblemente infladas que ni siquiera me permitían cambiar miles y separadores decimales. 17 de marzo a las 9:12
81

Esta es una variación de la respuesta de @ mikez302, pero modificada para admitir números con decimales (según los comentarios de @ neu-rah de que numberWithCommas (12345.6789) -> "12,345.6,789" en lugar de "12,345.6789"

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
1
78
function formatNumber (num) {
    return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

print(formatNumber(2665));      // 2,665
print(formatNumber(102665));    // 102,665
print(formatNumber(111102665)); // 111,102,665
6
  • ¿Qué hace esto que mi respuesta no hace? La expresión regular se ve ligeramente diferente, pero parece que debería hacer lo mismo. 19 de agosto de 2014 a las 22:14
  • 6
    Esto es elegante. Exactamente lo que estaba buscando. 7/10/2014 a las 18:23
  • 4
    ¿De blog.tompawlak.org/number-currency-formatting-javascript ? Problema conocido: formatNumber (0.123456) = 0.123,456 La ausencia de lookbehind en JS hace que sea difícil solucionarlo con una elegante expresión regular.
    Vlad
    20 de enero de 2015 a las 2:48
  • esto permite caracteres como abcdef, etc., que deberían estar restringidos. 26 de mayo de 2016 a las 13:09
  • 1
    123456789.123456789.toString (). Replace (/ (\ d) (? = (\ D {3}) + \.) / G, '$ 1,') => 123,456,789.12345679 24 jul 2017 a las 10:30
60

Usando expresión regular

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789

console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

Usando toLocaleString ()

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

ref MDN: Number.prototype.toLocaleString ()

Usando Intl.NumberFormat ()

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));

// expected output: "1,23,000"

ref Intl.NumberFormat

DEMO AQUÍ

<script type="text/javascript">
  // Using Regular expression
  function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }

  function commas() {
    var num1 = document.myform.number1.value;

    // Using Regular expression
    document.getElementById('result1').value = toCommas(parseInt(num1));
    // Using toLocaleString()

    document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    });

    // Using Intl.NumberFormat()
    document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    }).format(num1);
  }
</script>
<FORM NAME="myform">
  <INPUT TYPE="text" NAME="number1" VALUE="123456789">
  <br>
  <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
  <br>Using Regular expression
  <br>
  <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
  <br>Using toLocaleString()
  <br>
  <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
  <br>Using Intl.NumberFormat()
  <br>
  <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">

</FORM>

Rendimiento

Rendimiento http://jsben.ch/sifRd

2
  • Esto no funciona si está escribiendo dinámicamente. Si solo le da un valor, funciona, pero si está alimentando un valor de manera dinámica y constante, las comas se agregan en el lugar incorrecto. 16/08/18 a las 22:46
  • He actualizado la demostración debajo de mi respuesta. Al ingresar un valor dinámico en un cuadro de texto. prueba prueba @EdgarQuintero 17 de agosto de 2018 a las 1:32
44

Formato de número internacional

Función JS nativa. Compatible con IE11, Edge, la última versión de Safari, Chrome, Firefox, Opera, Safari en iOS y Chrome en Android.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
1
  • Mi respuesta se actualizó en respuesta a sus comentarios. ¡Gracias! 14/11/2017 a las 16:23
39

Estoy bastante impresionado por la cantidad de respuestas que tiene esta pregunta. Me gusta la respuesta de uKolka :

n.toLocaleString()

Pero desafortunadamente, en algunos lugares como el español, no funciona (en mi humilde opinión) como se esperaba para números por debajo de 10,000:

Number(1000).toLocaleString('ES-es')

Da 1000y no 1.000.

Consulte toLocaleString no funciona con números inferiores a 10000 en todos los navegadores para saber por qué.

Entonces tuve que usar la respuesta de Elias Zamaria eligiendo el carácter separador de miles correcto:

n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Este funciona bien como una línea para ambas configuraciones regionales que usan ,o .como separador de miles y comienza a trabajar desde 1,000 en todos los casos.

Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Da 1.000con un contexto local en español.

Si desea tener un control absoluto sobre la forma en que se formatea un número, también puede intentar lo siguiente:

let number   = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)

let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
  i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)

console.log(final)

Da 1,234.57.

Éste no necesita una expresión regular. Funciona ajustando el número a la cantidad deseada de decimales con toFixedprimero, luego dividiéndolo alrededor del punto decimal .si hay uno. Luego, el lado izquierdo se convierte en una matriz de dígitos que se invierte. Luego, se agrega un separador de miles cada tres dígitos desde el principio y el resultado se invierte nuevamente. El resultado final es la unión de las dos partes. El signo del número de entrada se quita Math.absprimero y luego se vuelve a colocar si es necesario.

No es de una sola línea, pero no es mucho más largo y se convierte fácilmente en una función. Se han agregado variables para mayor claridad, pero pueden ser sustituidas por sus valores deseados si se conocen de antemano. Puede usar las expresiones que se usan toLocaleStringcomo una forma de averiguar los caracteres correctos para el punto decimal y el separador de miles para la configuración regional actual (tenga en cuenta que estos requieren un Javascript más moderno).

0
36

Gracias a todos por sus respuestas. Me he basado en algunas de las respuestas para crear una solución más "única para todos".

El primer fragmento añade una función que imita PHP Es number_format()el prototipo de Número. Si estoy formateando un número, generalmente quiero lugares decimales para que la función tome el número de lugares decimales para mostrar. Algunos países usan comas como decimal y decimales como separador de miles, por lo que la función permite establecer estos separadores.

Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.toFixed(decimals).split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);

    return parts.join(dec_point);
}

Usaría esto de la siguiente manera:

var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00

Descubrí que a menudo necesitaba recuperar el número para las operaciones matemáticas, pero parseFloat convierte 5,000 a 5, simplemente tomando la primera secuencia de valores enteros. Así que creé mi propia función de conversión flotante y la agregué al prototipo String.

String.prototype.getFloat = function(dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.split(dec_point);
    var re = new RegExp("[" + thousands_sep + "]");
    parts[0] = parts[0].replace(re, '');

    return parseFloat(parts.join(dec_point));
}

Ahora puede usar ambas funciones de la siguiente manera:

var foo = 5000;
var fooString = foo.numberFormat(2); // The string 5,000.00
var fooFloat = fooString.getFloat(); // The number 5000;

console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00
7
  • 2
    Muy bonito, tomé prestado el primer método;) Pero no produce un resultado correcto cuando quieres usar un formato europeo y el número es fraccionario. La línea 5 debe ser:var parts = this.toFixed(decimals).toString().split('.');
    vbwx
    10 de julio de 2013 a las 1:13
  • ¡Tienes razón! toFixed () cambia la coma a un punto y, por lo tanto, el '.' debe usarse en lugar de var dec_point. Gracias por señalar eso.
    None
    11/07/2013 a las 0:40
  • ¿Puedes hacer un módulo npm para esto?
    chovy
    10 de enero de 2014 a las 8:08
  • 3
    @ J.Money El .toString no es necesario, toFixed ya devuelve una cadena.
    Ariel
    8 de julio de 2014 a las 7:56
  • No sé por qué ha mencionado PHP aquí en absoluto, o dado una función prototípica que ya existe
    vsync
    22 de agosto de 2015 a las 8:47
25

Creo que esta es la expresión regular más corta que lo hace:

/\B(?=(\d{3})+\b)/g

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")

Lo verifiqué en algunos números y funcionó.

3
  • sólo funciona bien si no tiene un número flotante con más de 3 números después del separador, en este caso un punto. De lo contrario, también agrega una coma. "1234567890.1234567890" .replace (/ \ B (? = (\ D {3}) + \ b) / g, ",") Esto no funcionaría, por ejemplo. Devuelve "1.234.567.890,1.234.567.890"
    Marcio
    22/07/2015 a las 10:49
  • 1
    ¡Funciona bien para la moneda! Redondea tus dígitos antes de agregar comas. 18 de septiembre de 2015 a las 18:04
  • 1
    Agrega, después del punto decimal: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3,456 9 de junio de 2017 a las 10:06
22

Number.prototype.toLocaleString()Hubiera sido increíble si todos los navegadores lo hubieran proporcionado de forma nativa (Safari) .

Revisé todas las demás respuestas, pero nadie pareció rellenarlas. Aquí hay un poc hacia eso, que en realidad es una combinación de las dos primeras respuestas; si toLocaleStringfunciona, lo usa, si no lo hace, usa una función personalizada.

var putThousandsSeparators;

putThousandsSeparators = function(value, sep) {
  if (sep == null) {
    sep = ',';
  }
  // check if it needs formatting
  if (value.toString() === value.toLocaleString()) {
    // split decimals
    var parts = value.toString().split('.')
    // format whole numbers
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
    // put them back together
    value = parts[1] ? parts.join('.') : parts[0];
  } else {
    value = value.toLocaleString();
  }
  return value;
};

alert(putThousandsSeparators(1234567.890));
4
  • 1
    Tenga en cuenta que el polyfill solo funciona con números que tengan como máximo 3 decimales. Por ejemplo: 0.12345saldrá 0.12,345. Se puede encontrar una buena implementación para esto en el guión bajo.
    Andy
    28/02/2017 a las 14:20
  • tiene razón, poner una value > 1000condición if corrige ese caso, sin embargo, esto fue un poc y, por supuesto, se pueden encontrar versiones mejor probadas en otros lugares, gracias por señalarlo.
    Sinan
    28 feb 2017 a las 19:28
  • 1
    No es suficiente poner value > 1000, porque sería lo mismo para cualquier número y más de 3 decimales. por ejemplo, 1000.12345devoluciones 1,000.12,345. Su respuesta es excelente y está en el camino correcto, pero no completa. Solo estaba tratando de señalar a otras personas que pueden tropezar con su respuesta y simplemente copiarla sin probarla con diferentes datos de entrada.
    Andy
    1 de marzo de 2017 a las 7:59
  • 1
    bien, esto necesitaba otra edición :) Estoy de acuerdo, pero ahora al menos debería funcionar en la mayoría de los casos.
    Sinan
    1/03/2017 a las 22:17
21

El separador de miles se puede insertar de manera internacional utilizando el Intlobjeto del navegador :

Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example

Consulte el artículo de MDN sobre NumberFormat para obtener más información, puede especificar el comportamiento de la configuración regional o el valor predeterminado del usuario. Esto es un poco más infalible porque respeta las diferencias locales; muchos países utilizan puntos para separar dígitos, mientras que una coma indica los decimales.

Intl.NumberFormat aún no está disponible en todos los navegadores, pero funciona en las últimas versiones de Chrome, Opera e IE. La próxima versión de Firefox debería admitirlo. Webkit no parece tener un cronograma para la implementación.

4
  • 2
    Si bien esto sería increíble si pudiéramos usar una función incorporada simple, tiene una implementación de navegador terrible. Por ejemplo, IE 8-10 y todos los Safari no admiten este 2 de septiembre de 2014 a las 14:45
  • @BlaineKasten hay un polyfill totalmente compatible para navegadores más antiguos disponible aquí: github.com/andyearnshaw/Intl.js es enorme, pero funciona.
    Mahn
    8 de diciembre de 2014 a las 13:58
  • 1
    Disponible a través de un CDN pollyfill (solo devuelve lo que se necesita según useragent ): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
    Kevin
    30/09/15 a las 22:09
  • Tuve problemas para formatear números grandes con toLocaleString, esto funcionó muy bien (con polyfill) 23/08/2016 a las 18:58
20

Puede utilizar este procedimiento para formatear la moneda que necesita.

var nf = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’

Para más información puede acceder a este enlace.

https://www.justinmccandless.com/post/formatting-currency-in-javascript/

1
  • Esta es la respuesta nativa, portátil y correcta. Ojalá pudiera votar a favor más de una vez. 21/06/18 a las 19:48
16

si está tratando con valores de moneda y formateando mucho, entonces podría valer la pena agregar un pequeño archivo Accounting.js que maneja muchos casos extremos y localización:

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

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

// Negative values are formatted nicely, too:
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
1
14

El siguiente código usa el escaneo de caracteres, por lo que no hay expresiones regulares.

function commafy( num){
  var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
  while(i--){ o = (i===0?'':((L-i)%3?'':',')) 
                  +s.charAt(i) +o }
  return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); 
}

Muestra un rendimiento prometedor: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Corrección menor para resolver el problema cuando num <0. Ver https://jsfiddle.net/runsun/p5tqqvs3/

3
  • esto no funciona con commafy(-123456)eso da-,123,456 13 mar.14 a las 16:37
  • ¡Esto es genial! Gracias por armar el jsperf 24/09/15 a las 21:14
  • Este fragmento es un monstruo absoluto, supera a todo. 15 de enero de 2016 a las 5:46
14

Aquí hay una función simple que inserta comas para miles de separadores. Utiliza funciones de matriz en lugar de una expresión regular.

/**
 * Format a number as a string with commas separating the thousands.
 * @param num - The number to be formatted (e.g. 10000)
 * @return A string representing the formatted number (e.g. "10,000")
 */
var formatNumber = function(num) {
    var array = num.toString().split('');
    var index = -3;
    while (array.length + index > 0) {
        array.splice(index, 0, ',');
        // Decrement by 4 since we just added another unit to the array.
        index -= 4;
    }
    return array.join('');
};

Enlace CodeSandbox con ejemplos: https://codesandbox.io/s/p38k63w0vq

2
  • 2
    Hola .. Este ejemplo es genial. Pero también pondrá comas para la parte decimal. sólo una edición: function formatNumber (num) {var decimalPart = ''; num = num.toString (); if (num.indexOf ('.')! = -1) {decimalPart = '.' + num.split ('.') [1]; num = parseInt (num.split ('.') [0]); } var matriz = num.toString (). split (''); var index = -3; while (matriz.longitud + índice> 0) {matriz.splice (índice, 0, ','); // Disminuir en 4 ya que acabamos de agregar otra unidad a la matriz. índice - = 4; } return array.join ('') + decimalPart; };
    Aki143S
    25 de septiembre de 2012 a las 7:53
  • Gracias Señor. Esto es exactamente lo que necesitaba.
    Arad
    22/06/19 a las 20:05
14

Use este código para manejar el formato de moneda para la India. El código de país se puede cambiar para manejar la moneda de otro país.

let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);

producción:

3,50,256.95
2
  • Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre cómo y / o por qué resuelve el problema mejoraría el valor de la respuesta a largo plazo. Lee esto . 12/03/19 a las 10:21
  • @ShanteshwarInde agregaré contexto adicional para mejorar la respuesta seguro 12/03/19 a las 10:32
13
var number = 2561556862056.12;

console.log(new Intl.NumberFormat().format(number));

Esta es la forma más fácil que encontré

1
12

También puede utilizar el constructor Intl.NumberFormat . Aquí sabrás como podrás hacerlo.

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 
1
  • este nodo js no funciona. No está dando respuesta en formato indio. 28 de mayo de 2020 y 12:40 p.m.
9

Mi respuesta es la única respuesta que reemplaza por completo a jQuery con una alternativa mucho más sensata:

function $(dollarAmount)
{
    const locale = 'en-US';
    const options = { style: 'currency', currency: 'USD' };
    return Intl.NumberFormat(locale, options).format(dollarAmount);
}

Esta solución no solo agrega comas, sino que también se redondea al centavo más cercano en caso de que ingrese una cantidad como la $(1000.9999)que obtendrá $ 1,001.00. Además, el valor que ingresa puede ser un número o una cadena; No importa.

Si está tratando con dinero, pero no quiere que se muestre un signo de dólar al principio de la cantidad, también puede agregar esta función, que usa la función anterior pero elimina $:

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}

Si estás no se trata de dinero, y tienen diferentes requisitos de formato decimal, he aquí una función más versátil:

function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
    const options = {};
    options.maximumFractionDigits = maxDecimalPlaces;
    options.minimumFractionDigits = minDecimalPlaces;
    return Intl.NumberFormat('en-US',options).format(number);
}

Ah, y por cierto, el hecho de que este código no funcione en alguna versión antigua de Internet Explorer es completamente intencional. Intento romper IE cada vez que puedo detectar que no es compatible con los estándares modernos.

Recuerde que los elogios excesivos, en la sección de comentarios, se consideran fuera de tema. En cambio, colócame con votos a favor.

2
  • 1
    El Number (n) .toLocaleString () parece la mejor respuesta, pero probablemente desee usar algo como el nuevo Intl.NumberFormat ('en-US'). Format (n) en lugar de quitar los signos de dólar y los decimales si todos los el usuario quiere comas en su número. 19 de septiembre de 2019 a las 1:15
  • @bmacnaughton: Ese es un buen punto cuando no se trata de dinero. Sin embargo, si está tratando con dinero, y simplemente "no quiere el signo de dólar inicial", Number (1000.50) .toLocaleString () produce '1,000.5', que elimina el cero insignificante que normalmente se mantiene cuando se muestran valores monetarios. Sin embargo, es un buen comentario: todo el mundo debería saber lo que ha dicho. 19 de septiembre de 2019 a las 8:57
8

Escribí este antes de tropezar con este artículo. Sin expresiones regulares y realmente puedes entender el código.

$(function(){
  
  function insertCommas(s) {

    // get stuff before the dot
    var d = s.indexOf('.');
    var s2 = d === -1 ? s : s.slice(0, d);

    // insert commas every 3 digits from the right
    for (var i = s2.length - 3; i > 0; i -= 3)
      s2 = s2.slice(0, i) + ',' + s2.slice(i);

    // append fractional part
    if (d !== -1)
      s2 += s.slice(d);

    return s2;

  }
  
  
  $('#theDudeAbides').text( insertCommas('1234567.89012' ) );
  
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="theDudeAbides"></div>
2
  • 1
    Agregué s.toString () al comienzo de la función para que también pueda aceptar números, no solo cadenas. Esta es mi respuesta preferida porque es legible, concisa y no tiene ninguno de los errores que parecen tener las respuestas de expresiones regulares. 12 de enero de 2016 a las 23:19
  • solo funciona si le pasas una cadena ... una solución fácil, pero solo quería anotarlo
    ladieu
    25 de agosto a las 18:08
8
var formatNumber = function (number) {
  var splitNum;
  number = Math.abs(number);
  number = number.toFixed(2);
  splitNum = number.split('.');
  splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return splitNum.join(".");
}

EDITAR: La función solo funciona con números positivos. por ejemplo:

var number = -123123231232;
formatNumber(number)

Resultado: "123,123,231,232"

Pero para responder a la pregunta anterior, el toLocaleString()método simplemente resuelve el problema.

var number = 123123231232;
    number.toLocaleString()

Resultado: "123,123,231,232"

¡Alegría!

2
  • 1
    Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre cómo y / o por qué resuelve el problema mejoraría el valor de la respuesta a largo plazo. 10/06/2017 a las 19:48
  • 1
    Buen guión, pero no funciona con números negativos. 26/01/18 a las 18:50
6

Permítanme intentar mejorar la respuesta de uKolka y tal vez ayudar a otros a ahorrar algo de tiempo.

Utilice Numeral.js .

document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>

Debería utilizar Number.prototype.toLocaleString () solo si la compatibilidad de su navegador no es un problema.

1
  • esto me inspiró a instalar npm numeral 17/06/15 a las 15:38
6

Solo para futuros Googlers (o no necesariamente 'Googlers'):

Todas las soluciones mencionadas anteriormente son maravillosas, sin embargo, la expresión regular podría ser terriblemente mala para usar en una situación como esa.

Entonces, sí, puede usar algunas de las opciones propuestas o incluso escribir algo primitivo pero útil como:

const strToNum = str => {

   //Find 1-3 digits followed by exactly 3 digits & a comma or end of string
   let regx = /(\d{1,3})(\d{3}(?:,|$))/;
   let currStr;

   do {
       currStr = (currStr || str.split(`.`)[0])
           .replace( regx, `$1,$2`)
   } while (currStr.match(regx)) //Stop when there's no match & null's returned

   return ( str.split(`.`)[1] ) ?
           currStr.concat(`.`, str.split(`.`)[1]) :
           currStr;

};

strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987

La expresión regular que se usa aquí es bastante simple y el ciclo se ejecutará exactamente la cantidad de veces que se necesita para hacer el trabajo.

Y puede optimizarlo mucho mejor, código "DRYify" y así sucesivamente.

Todavía,

(-1234567.0987).toLocaleString();

(en la mayoría de las situaciones) sería una opción mucho mejor.

El punto no está en la velocidad de ejecución o en la compatibilidad entre navegadores.

En situaciones en las que le gustaría mostrar el número resultante al usuario, el método .toLocaleString () le da el superpoder para hablar el mismo idioma con el usuario de su sitio web o aplicación (cualquiera que sea su idioma).

Este método de acuerdo con la documentación de ECMAScript se introdujo en 1999, y creo que la razón fue la esperanza de que Internet en algún momento conectará a personas de todo el mundo, por lo que se necesitaban algunas herramientas de "internalización".

Hoy en día Internet nos conecta a todos, así que es importante recordar que el mundo es mucho más complejo de lo que podríamos imaginar y que (/ casi) todos estamos aquí , en Internet.

Obviamente, considerando la diversidad de personas, es imposible garantizar una UX perfecta para todos porque hablamos diferentes idiomas, valoramos diferentes cosas, etc. Y precisamente por eso, es aún más importante tratar de localizar las cosas tanto como sea posible. .

Entonces, considerando que existen algunos estándares particulares para la representación de fecha, hora, números, etc. y que tenemos una herramienta para mostrar esas cosas en el formato preferido por el usuario final, ¿no es tan raro y casi irresponsable no hacerlo? utilizar esa herramienta (especialmente en situaciones en las que queremos mostrar estos datos al usuario)?

Para mí, usar RegExp en lugar de .toLocaleString () en una situación como esa suena un poco como crear una aplicación de reloj con JavaScript y codificarla de tal manera que solo muestre la hora de Praga (lo que sería bastante inútil para personas que no viven en Praga) a pesar de que el comportamiento predeterminado de

new Date();

es devolver los datos de acuerdo con el reloj del usuario final.

3
  • ¿Por qué escribiste la función con const y =>?
    OG Sean
    15/08/19 a las 20:18
  • @OGSean Siempre lo hago, ya que es la forma más conveniente de declarar variables y funciones. Además, creo que ayuda a mantener el código más limpio y más corto. 15/08/19 a las 20:38
  • Esta es la respuesta correcta, la gente lo está complicando demasiado. toLocaleString()está construido para este caso de uso exacto. 4 de mayo a las 12:48
6

Una forma alternativa, apoyando decimales, diferentes separadores y negativos.

var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
    var ts      = ( thousand_sep == null ? ',' : thousand_sep )
        , ds    = ( decimal_sep  == null ? '.' : decimal_sep )
        , dp    = ( decimal_pos  == null ? 2   : decimal_pos )

        , n     = Math.floor(Math.abs(number)).toString()

        , i     = n.length % 3 
        , f     = ((number < 0) ? '-' : '') + n.substr(0, i)
    ;

    for(;i<n.length;i+=3) {
        if(i!=0) f+=ts;
        f+=n.substr(i,3);
    }

    if(dp > 0) 
        f += ds + parseFloat(number).toFixed(dp).split('.')[1]

    return f;
}

Algunas correcciones de @Jignesh Sanghani, no olvides votar a favor de su comentario.

6
  • Perfecto para mí, acabo de agregar una nueva línea para eliminar el formato antes de procesar. 21/03/2016 a las 14:50
  • 3
    fn.substr(0, i)reemplazar con n.substr(0, i)y también number.toFixed(dp).split('.')[1]reemplazar con parseFloat(number).toFixed(dp).split('.')[1]. porque cuando lo uso directamente me da un error. por favor actualice su código 13/07/19 a las 8:12
  • defectuoso. el número crece. una llamada de examen hubiera sido genial!
    mmm
    20/08/19 a las 15:54
  • El cambio de techo a piso arregló eso, pero no estoy seguro de qué otros problemas surgirán.
    mmm
    20/08/19 a las 15:56
  • 1
    Prueba Math.floor (-75.1);)
    mmm
    6/11/19 a las 20:54
5

Creo que esta función se encargará de todos los problemas relacionados con este problema.

function commaFormat(inputString) {
    inputString = inputString.toString();
    var decimalPart = "";
    if (inputString.indexOf('.') != -1) {
        //alert("decimal number");
        inputString = inputString.split(".");
        decimalPart = "." + inputString[1];
        inputString = inputString[0];
        //alert(inputString);
        //alert(decimalPart);

    }
    var outputString = "";
    var count = 0;
    for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
        //alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
        if (count == 3) {
            outputString += ",";
            count = 0;
        }
        outputString += inputString.charAt(i);
        count++;
    }
    if (inputString.charAt(0) == '-') {
        outputString += "-";
    }
    //alert(outputString);
    //alert(outputString.split("").reverse().join(""));
    return outputString.split("").reverse().join("") + decimalPart;
}
5

Para cualquier persona a la que le gusten las expresiones regulares y una sola expresión regular, pero no quiera usar split (), aquí hay una versión mejorada de la expresión regular de otras respuestas que maneja (ignora) los lugares decimales:

    var formatted = (x+'').replace(/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g, (digit, fract) => fract || digit + ',');

La expresión regular primero coincide con una subcadena que comienza con un literal "." y lo reemplaza por sí mismo ("fract"), y luego coincide con cualquier dígito seguido de múltiplos de 3 dígitos y pone "," después de él.

Por ejemplo, x = 12345678.12345678 dará formato = '12, 345,678.12345678 '.

5

Si está buscando una solución corta y dulce:

const number = 12345678.99;

const numberString = String(number).replace(
    /^\d+/,
    number => [...number].map(
        (digit, index, digits) => (
            !index || (digits.length - index) % 3 ? '' : ','
        ) + digit
    ).join('')
);

// numberString: 12,345,678.99
4
  • Eso me dice "Error de tipo no detectado: el número no es iterable". Quizás necesites llamar toStringal número. 17 dic.20 a las 20:04
  • @EliasZamaria lo siento, usé una cadena en mi caso. Actualicé mi respuesta para convertirla en cadena. 17/12/20 a las 20:12
  • Probé 12.34 como el número y regresó 12,.34. 17/12/20 a las 21:57
  • Pensé que solo estaba destinado a trabajar con decimales. Actualizado para ti. 17 dic.20 a las 23:08
4

Agregué tofixed a la solución de Aki143S . Esta solución utiliza puntos para separadores de miles y comas para la precisión.

function formatNumber( num, fixed ) { 
    var decimalPart;

    var array = Math.floor(num).toString().split('');
    var index = -3; 
    while ( array.length + index > 0 ) { 
        array.splice( index, 0, '.' );              
        index -= 4;
    }

    if(fixed > 0){
        decimalPart = num.toFixed(fixed).split(".")[1];
        return array.join('') + "," + decimalPart; 
    }
    return array.join(''); 
};

Ejemplos;

formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454