El dinero ama el orden: ¿cómo convertir un número en un precio atractivo en JavaScript?
Imagina: estás escribiendo una tienda en línea. El servidor devuelve el precio de un producto — simplemente el número 1999.5. Mostrar al usuario un número "crudo" es de mala educación. El cliente quiere ver "$1,999.50" o, si estás en España, "1.999,50 €".
Esta pregunta atormenta a miles de desarrolladores en Stack Overflow. Hoy, de una vez por todas, entenderemos cómo formatear correctamente números a cadenas de moneda en JavaScript. Aprenderás sobre los métodos integrados, sus particularidades y cuándo es mejor usar cada uno.
¿Por qué simplemente .toFixed(2) es una mala idea?
Muchos principiantes hacen esto:
const price = 1999.5;console.log('$' + price.toFixed(2)); // "$1999.50"Parece que funciona. Pero esto es una bomba de tiempo. ¿Por qué?
- Sin separadores de miles. $1999.50 se lee peor que $1,999.50.
- Sin localización. En Europa, la coma es el separador decimal, el punto es el separador de miles. Tu código se romperá.
- El símbolo de moneda está hardcodeado. Cambiar $ por € significa modificar el código.
Por suerte, el JavaScript moderno nos proporciona herramientas elegantes. Vamos a estudiarlas.
Método n.º 1: Intl.NumberFormat — el rey del formateo (recomendado)
Este objeto es parte de la API de Internacionalización. Está creado específicamente para trabajar con locales, monedas y números. Es la forma más correcta y flexible.
Ejemplo básico
const formatter = new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'EUR'});
console.log(formatter.format(1999.5)); // "1.999,50 €"¡Listo! JavaScript mismo colocó los puntos, las comas y añadió el símbolo del euro. Magia, ¿verdad?
¿Cómo funciona?
El constructor acepta dos argumentos:
- locales — una cadena con el código de locale (por ejemplo,
'en-US','de-DE','es-ES'). - options — un objeto de configuración. Clave:
style: 'currency'ycurrency: 'USD'.
Configuración para cualquier moneda
¿Quieres dólares para EE. UU.?
const usFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD'});console.log(usFormatter.format(2500)); // "$2,500.00"¿Euros para Alemania?
const deFormatter = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR'});console.log(deFormatter.format(2500)); // "2.500,00 €"Observa: en Alemania, el punto es el separador de miles y la coma es el signo decimal. Intl lo hace todo por ti.
Opciones adicionales
¿Quieres eliminar la parte fraccionaria (sin céntimos)?
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0});console.log(formatter.format(1999.5)); // "$2,000" (redondeó)¿Necesitas mostrar siempre 4 decimales? Por supuesto:
const preciseFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4});console.log(preciseFormatter.format(1.2)); // "$1.2000"Ventajas: nativo, rápido, soporta todas las monedas del mundo, cambia fácilmente de locale.
Desventajas: no funciona en navegadores muy antiguos (IE 10 e inferiores — pero eso ya es historia).
Método n.º 2: Number.prototype.toLocaleString() — rápido y sencillo
Este método es el "hermano pequeño" de Intl.Num