EmoArt
Publicar
Glosario

UTF-16 - la codificación detrás de las cadenas de JavaScript

Última actualización: 2026-05-23·Aprox. 4 min

Este artículo se lee en unos 4 minutos.

Si tu código JavaScript dice que "🌸".length es 2, ya te has encontrado con UTF-16. Esta codificación es invisible hasta que los emojis entran en escena.UTF-16 es una codificación Unicode que representa la mayoría de caracteres en 2 bytes y los caracteres suplementarios (incluidos la mayoría de emojis) en 4 bytes mediante pares sustitutos. Es la representación interna de cadenas en JavaScript, Java, C# y partes de Windows. Entender sus peculiaridades es esencial para manejar emojis correctamente.

Definición

UTF-16 (16-bit Unicode Transformation Format) codifica puntos de código Unicode en secuencias de unidades de código de 16 bits. Los puntos de código del Plano Multilingüe Básico (BMP, U+0000 a U+FFFF) ocupan una unidad de 16 bits (2 bytes). Los puntos de código por encima de U+FFFF se codifican como pares sustitutos - dos unidades de 16 bits juntas (4 bytes en total).

La estructura de dos niveles

Rango de puntos de códigoUnidades de códigoBytesEjemplos
U+0000 - U+FFFF (BMP)12ASCII, latín, caracteres CJK
U+10000 - U+10FFFF2 (par sustituto)4La mayoría de emojis, escrituras antiguas

Pares sustitutos

Para puntos de código por encima de U+FFFF, UTF-16 divide el valor en dos unidades de código de 16 bits:

  • Sustituto alto: U+D800 a U+DBFF (1024 valores posibles)
  • Sustituto bajo: U+DC00 a U+DFFF (1024 valores posibles)

La combinación produce 1024 × 1024 = 1 048 576 puntos de código posibles, cubriendo exactamente el plano suplementario (U+10000 a U+10FFFF). Los valores sustitutos están reservados y nunca aparecen como caracteres independientes en texto Unicode válido.

Ejemplo: 🌸 (U+1F338)

El emoji de flor de cerezo en el punto de código U+1F338 se codifica como:

  • Sustituto alto: 0xD83C
  • Sustituto bajo: 0xDF38
  • Bytes UTF-16: D8 3C DF 38 (4 bytes en total)

En una cadena JavaScript, esto se almacena como dos unidades de código. "🌸".length devuelve 2 porque length cuenta unidades de código, no puntos de código.

Dónde se usa UTF-16

  • JavaScript: String internamente; length, charAt, charCodeAt operan sobre unidades de código
  • Java: String y char son UTF-16
  • C# / .NET: string es UTF-16
  • API de Windows: muchas APIs usan UTF-16 para cadenas
  • Qt, Cocoa, ICU: UTF-16 internamente para muchas operaciones de cadenas

UTF-8, en cambio, es el formato dominante en la transmisión (HTTP, JSON, archivos). Muchos sistemas usan UTF-8 para almacenamiento y transporte, y UTF-16 para el procesamiento en memoria.

Las trampas en JavaScript

length vs. caracteres visibles

"a".length              // 1
"あ".length             // 1 (BMP)
"🌸".length             // 2 (par sustituto)
"👨‍👩‍👧".length            // 8 (3 emojis + 2 ZWJ en pares sustitutos)
[..."🌸"].length        // 1 (iteración por puntos de código)
[..."👨‍👩‍👧"].length       // 5 (puntos de código, no grafemas)

Invertir cadenas rompe los emojis

"🌸".split("").reverse().join("")
// Roto: los sustitutos se separan, se muestra como ?? o caracteres inválidos

[..."🌸"].reverse().join("")
// Correcto: inversión consciente de puntos de código

// Aún mejor: usar Intl.Segmenter para clústeres de grafemas

charCodeAt devuelve unidades de código sustituto

"🌸".charCodeAt(0) devuelve 55356 (0xD83C, el sustituto alto), no el punto de código 127800. Usa codePointAt(0) para obtener el punto de código real, que combina los sustitutos.

Comparación UTF-8 vs. UTF-16

AspectoUTF-8UTF-16
Tamaño ASCII1 byte2 bytes
Tamaño CJK3 bytes2 bytes
Tamaño emoji4 bytes4 bytes
AutosincronizaciónSí (mediante rangos sustitutos)
EndiannessNingunoExisten variantes BE/LE

Errores comunes

  • ❌ «UTF-16 siempre usa 2 bytes por carácter» → ✅ Los caracteres suplementarios usan 4 bytes mediante pares sustitutos
  • ❌ «str.length devuelve el número de caracteres» → ✅ Devuelve el número de unidades de código en UTF-16
  • ❌ «UTF-16 se está quedando obsoleto» → ✅ Está profundamente integrado en JavaScript, Java, .NET y las APIs de Windows, y no va a desaparecer pronto

Términos relacionados

  • Unicode - lo que UTF-16 codifica
  • ZWJ - secuencias que abarcan múltiples pares sustitutos

¿Te resultó útil este artículo?