Formatando números e moedas com toLocaleString()
Tags: javascript, tolocalestring, html, web
Published: 2022-03-21 05:03:06

---
title: Formatando números e moedas com toLocaleString()
published: true
description: O método Number.prototype.toLocaleString() permite formatar um número de acordo com a nacionalidade desejada.
tags: javascript, toLocaleString, html, web, 
cover_image: https://i.imgur.com/tWjiOSp.png
---

O método [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) permite formatar um número de acordo com a nacionalidade desejada. A partir de uma entrada do tipo `number`, ele devolve uma `string` com a formatação padrão ou a que foi definida através das opções disponíveis.

Conteúdo:

1. [Números](#números)
    1. [Estilo `decimal`](#estilo-decimal)
        1. [Separadores de milhar](#separadores-de-milhar)
            1. [Desabilitando separadores de milhar](#desabilitando-separadores-de-milhar)
        2. [Inteiros e dígitos fracionados (casas decimais)](#inteiros-e-dígitos-fracionados-casas-decimais)
            1. [`minimumIntegerDigits`](#minimumintegerdigits)
            2. [`minimumFractionDigits`](#minimumfractiondigits)
            3. [`maximumFractionDigits`](#maximumfractiondigits)
            4. [`minimumSignificantDigits`](#maximumsignificantdigits)
            5. [`maximumSignificantDigits`](#maximumsignificantdigits)
    2. [Estilo `percent`](#estilo-percent)
        1. [Exibir valores entre 0% e 100%, onde 100% não está incluso](#exibir-valores-entre-0-e-100-onde-100-não-está-incluso)
        2. [Exibir valores maiores ou iguais a 100%](#exibir-valores-maiores-ou-iguais-a-100)
    3. [Estilo `currency`](#estilo-currency)
        1. [A opção `currencyDisplay`](#A%20opção%20%60currencyDisplay%60)
3. [Limitações](#limitações)
4. [Conclusão](#conclusão)
5. [Links para consulta](#links-úteis)

## Números

Para o método [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) são aceitos três estilos de formatação:

- `decimal` (default): para números simples
- `percent`: para porcentagem
- `currency`: para valores monetários

### Estilo `decimal`

É o valor padrão e está definido de forma implícita.

#### Separadores de milhar

Podemos definir os separadores de milhar de acordo com a [localidade do ambiente atual de hospedagem](https://tc39.es/ecma262/#sec-number.prototype.tolocalestring):

```javascript
const brazilPopulation = 213317639; 
brazilPopulation.toLocaleString();
// Output: "213.317.639"
```

Mas, se quisermos especificar de qual país queremos a formatação, basta passar uma `string` com a `tag` da linguagem de acordo com a [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) para qual desejamos formatar. 

Geralmente, essa `tag` é composta de uma ou mais `subtags`, sendo a primeira da linguagem principal e a segunda com o código do país, de acordo com a [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Exemplo: `pt-BR` ou `en-us`.

```javascript
const brazilPopulation = 213317639; 
brazilPopulation.toLocaleString('ja-JP');
// Output: "213,317,639"
```
##### Desabilitando separadores de milhar

Também podemos definir se queremos ou não usar separadores de milhares, definindo um valor booleano para a propriedade `useGrouping`, o valor default é `true`

```javascript
const brazilPopulation = 213317639;
brazilPopulation.toLocaleString('pt-BR', {useGrouping: false})
// Output "213317639"
```

#### Inteiros e Dígitos Fracionados (Casas Decimais):

O estilo padrão para formatação de [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) é decimal, porém podemos definir algumas opções:

##### `minimumIntegerDigits`:

- Define a quantidade mínima de **dígitos inteiros**
- Intervalo de Valores: 1 ~ 21
- Valor Default: 1

```javascript
const number = 10.175;
number.toLocaleString('pt-br', {style: 'decimal', minimumIntegerDigits: 5});
// Output: "00.010,175"
```
Repare que ele adiciona a quantidade de zeros à esquerda necessárias para compensar os dígitos faltantes.

##### `minimumFractionDigits`:

- Define a quantidade mínima de **dígitos fracionados**
- Intervalo de Valores: 1 ~ 20
- Valor Default: 0

```javascript
const number = 10.175;
number.toLocaleString('pt-br', {style: 'decimal', minimumFractionDigits: 10});
// Output: "10,17500000"
```
Semelhante a `minimumIntegerDigits`, adiciona zeros à direita para compensar os dígitos faltantes.

##### `maximumFractionDigits`:

- Define o **número máximo de dígitos fracionados**
- Intervalo de Valores: 0 ~ 20
- Valor Default: 3

```javascript
const number = 10.175;
number.toLocaleString('pt-br', {style: 'decimal', maximumFractionDigits: 1});
// Output: "10,2"
```
Aqui, ele arredonda os números de acordo com a [regras de arredondamento](https://pt.wikipedia.org/wiki/Arredondamento).


##### `minimumSignificantDigits`:

- Define a quantidade mínima de **dígitos [significantes](https://pt.wikipedia.org/wiki/Algarismo_significativo)** 
- Intervalo de Valores: 1 ~ 21.
- Valor Default: 1

```javascript
const number = 10.175;
number.toLocaleString('pt-br', {style: 'decimal', minimumSignificantDigits: 10});
// Output: "10,17500000"
```
Diferente de `minimumIntegerDigits`, ele não adiciona zeros à esquerda para compensar os dígitos faltantes e sim à direita.

##### `maximumSignificantDigits`:

- Define a **quantidade máxima de dígitos [significantes](https://pt.wikipedia.org/wiki/Algarismo_significativo)** 
- Intervalo de Valores: 0 ~ 20.
- Valor Default: `minimumSignificantDigits`

```javascript
const number = 10.175;
number.toLocaleString('pt-br', {style: 'decimal', maximumSignificantDigits: 2});
// Output: "10"
number.toLocaleString('pt-br', {style: 'decimal', maximumSignificantDigits: 10});
// Output: "10,155"
```

### Estilo `percent`

Para estilizar números no formato percentual, precisamos definir a propriedade `style` como `percent`. Aqui vale lembrar que [porcentagem](https://mundoeducacao.uol.com.br/matematica/porcentagem.htm) é a divisão de um número qualquer por 100. Então, para:

#### Exibir valores entre 0% e 100%, onde 100% não está incluso

O valor a ser exibido deve estar entre 0 e 1, onde 1 não está incluso:

```javascript
const discount = 0.08179;
off.toLocaleString('pt-br', {style: 'percent'});
// Output: 8%
```

#### Exibir valores maiores ou iguais a 100%

O valor a ser exibido deve ser maior ou igual a 1:

```javascript
const discount = 8.179;
discount.toLocaleString('pt-br', {style: 'percent'});
// Output: "818%"
```

### Estilo `currency`

Para formatar valores monetários, precisamos definir a propriedade `style` como `currency`. Além disso, também é preciso usar a propriedade `currency` definindo seu valor com o código da moeda necessária de acordo com a [`ISO 4217`](https://pt.wikipedia.org/wiki/ISO_4217):

```javascript
const price = 2865.79;

price.toLocaleString('pt-BR', {style: 'currency', currency: 'BRL'});
// Output "R$ 2.865,79"

price.toLocaleString('ja-JP', {style: 'currency', currency: 'JPY'});
// Output "￥2,866"

price.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
// Output "$2,865.79"
```

#### A opção `currencyDisplay`
Podemos, ainda, definir como este valor será exibido. Valores aceitos:

- `name`: exibe nome da moeda
- `code`: exibe o código de acordo com a [`ISO 4217`](https://pt.wikipedia.org/wiki/ISO_4217)
- `symbol`(default): exibe o símbolo da moeda

```javascript
const price = 2865.79;

price.toLocaleString('pt-BR', {
    style: 'currency', 
    currency: 'BRL',
    currencyDisplay: 'name'
});
// Output "2.865,79 Reais brasileiros"

price.toLocaleString('pt-BR', {
    style: 'currency', 
    currency: 'BRL',
    currencyDisplay: 'code'
});
// Output "BRL 2.865,79"
```

## Limitações

A MDN recomenda que, caso exista um volume muito grande de números a serem formatados, é melhor criar um objeto [`Intl.NumberFormat`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) e usar o método [`Intl.NumberFormat.prototype.format()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format) para ter um ganho de performance.

## Conclusão

Considere o HTML a seguir:

```html
<span class="price"></span>
```
Sem [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString), precisaríamos fazer algo assim para obtermos uma apresentação minimamente aceitável de um valor monetário:

```javascript
const value = 25.978;
const priceContainer = document.querySelector('.price');
priceValueContainer.innerHTML = `R$ ${value.toFixed(2)}`;
```
Porém, usando [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString), podemos delegar a responsabilidade para o formatador:

```javascript
priceContainer.innerHTML = value.toLocaleString('pt-BR', {style: 'currency', currency: 'BRL'});
```
Ok, mas, no final das contas, ambos os códigos geram o mesmo resultado visual. Por que eu deveria usar [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) então?

Uma resposta possível seria para o seguinte caso:

Suponha que o nome da moeda do Brasil mude de Reais para Nárnia Reais e que o símbolo deixará de ser `R$` para se tornar `NR$`. A gente teria que sair atualizando tudo manualmente em nossa aplicação. Então, delegar essa responsabilidade para um método [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) pode agilizar essas modificações, pois ele usará as atualizações mais recentes dos códigos dos países.

E isso não é apenas para moedas, mas também para outros números. Imagine ter que formatar números grandes como a [população](https://pt.wikipedia.org/wiki/Lista_de_pa%C3%ADses_por_popula%C3%A7%C3%A3o) ou o [PBI](https://www.ibge.gov.br/explica/pib.php) de um país, por exemplo? 

Então, conhecer esse tipo de método torna-se interessante e um facilitador quando precisamos trabalhar com internacionalização. 

## Links para Consulta:

- MDN: 
    - [`Number.prototype.toLocaleString()`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString)
    - [`Intl.NumberFormat`](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat)
    - [`Intl.NumberFormat.prototype.format()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format)
- [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag)
- [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
- [ISO 4217](https://pt.wikipedia.org/wiki/ISO_4217)
- [Arredondamento](https://pt.wikipedia.org/wiki/Arredondamento)
- [Algarismo significativo](https://pt.wikipedia.org/wiki/Algarismo_significativo)