Contador de Caracteres: por que um emoji pode contar como 2
A contagem de caracteres desta ferramenta usa texto.length
— a propriedade nativa de string do JavaScript, que conta
unidades de código UTF-16, não "caracteres visuais" no
sentido intuitivo. Para texto em português, mesmo com acentuação, isso
coincide com a contagem intuitiva (cada letra, acentuada ou não,
corresponde a exatamente uma unidade de código). Mas para emojis fora
do Plano Multilíngue Básico do Unicode — a maioria dos emojis modernos
— cada um é representado por um par substituto (duas unidades de
código), então "😀".length retorna 2,
não 1, mesmo sendo visualmente um único caractere na tela.
Por que essa divergência não é um bug, é a definição da propriedade
.length nunca prometeu contar "caracteres visuais" — é,
por especificação da linguagem, uma contagem de unidades de código
UTF-16, herdada de decisões de design do JavaScript anteriores à
adoção ampla de emojis e outros caracteres do plano suplementar
Unicode. Para contar caracteres visuais de forma precisa (o que
inclui até emojis compostos por múltiplos pontos de código unidos por
um caractere de junção invisível, como uma família emoji formada por
4 pessoas em um único glifo), a ferramenta correta seria a API
Intl.Segmenter, que segmenta por "grapheme cluster" — a
unidade que um usuário reconheceria como "um caractere" — mas que tem
custo de processamento maior e nem sempre é necessária para o caso de
uso mais comum (contar caracteres de texto majoritariamente
alfanumérico, como um limite de tweet ou de campo de formulário).
Onde essa distinção importa na prática: limites de campo
Sistemas que impõem um limite de caracteres em um campo de formulário
(biografia, comentário, campo de SMS) e usam .length para
validar esse limite estão, tecnicamente, limitando por unidades de
código UTF-16, não por caracteres visuais — o que significa que um
texto cheio de emojis pode "gastar" o dobro (ou mais) do limite
aparente em comparação com o mesmo número de caracteres visuais em
texto puro. Para a maioria dos casos de uso, essa diferença é
aceitável e simples de explicar ao usuário; para sistemas que
precisam de contagem visualmente exata (como um contador de caracteres
de SMS, onde a codificação subjacente tem regras próprias e
diferentes), a contagem por unidade de código UTF-16 não é
suficiente.