He estado jugando con JS y no puedo entender cómo JS decide qué elementos agregar a la matriz creada cuando se usa Array.from()
. Por ejemplo, el siguiente emoji 👍 tiene un length
2, ya que está hecho de dos puntos de código, pero Array.from()
trata estos dos puntos de código como uno, dando una matriz con un elemento:
const emoji = '👍';
console.log(Array.from(emoji)); // Output: ["👍"]
Sin embargo, algunos otros personajes también tienen dos puntos de código como este personaje षि
(también tiene un .length
de 2). Sin embargo, Array.from
no "agrupa" este personaje y en su lugar produce dos elementos:
const str = 'षि';
console.log(Array.from(str)); // Output: ["ष", "ि"]
Mi pregunta es: ¿Qué determina si el carácter se divide (como en el ejemplo dos) o se trata como un solo elemento (como en el ejemplo uno) cuando el carácter consta de dos puntos de código?
javascript
string
unicode
iterator
Shnick
fuente
fuente
षि
son 2 caracteres separadoslength
. Iteradores o inclusoSet
no funciona con esoRespuestas:
Array.from
primero intenta invocar el iterador del argumento si tiene uno, y las cadenas tienen iteradores, por lo que invocaString.prototype[Symbol.iterator]
, así que veamos cómo funciona el método prototipo. Se describe en la especificación aquí :Mirar hacia arriba
CreateStringIterator
finalmente te lleva a lo21.1.5.2.1 %StringIteratorPrototype%.next ( )
que hace:Esto
CodeUnitCount
es lo que le interesa. Este número proviene de CodePointAt :Entonces, al iterar sobre una cadena con
Array.from
, devuelve un CodeUnitCount de 2 solo cuando el carácter en cuestión es el comienzo de un par sustituto. Los caracteres que se interpretan como pares sustitutos se describen aquí :षि
no es un par sustituto:Pero
👍
los personajes son:El primer código de carácter de
'👍'
es, en hexadecimal, D83D, que está dentro del rango0xD800 to 0xDBFF
de los sustitutos principales. Por el contrario, el primer código de caracteres'षि'
es mucho más bajo y no lo es. Entonces'षि'
se separa, pero'👍'
no lo hace.षि
se compone de dos caracteres distintos:ष
, devanagari Carta Ssa , yि
, devanagari vocal sesión I . Cuando están uno al lado del otro en este orden, se combinan gráficamente en un solo personaje visualmente, a pesar de estar compuestos por dos personajes separados.En contraste, los códigos de caracteres
👍
solo tienen sentido cuando están juntos como un solo glifo. Si intenta usar una cadena con cualquier punto de código sin el otro, obtendrá un símbolo sin sentido:fuente
षि
realidad son dos caracteres con puntos de código distintos combinados para formar un solo glifo (un carácter abstracto , tal como lo entienden los humanos). Esto está en contraste con el👍
emoji, que es un personaje completo en sí mismo, a pesar de que su punto de código es lo suficientemente alto como para que deba dividirse en un par sustituto. Creo que aclarar eso podría ayudar mucho a esta respuesta (por lo demás valiosa).UTF-16 (la codificación utilizada para cadenas en js) utiliza unidades de 16 bits. Por lo tanto, cada unicode que se puede representar con 15 bits se representa como un punto de código, todo lo demás como dos, conocidos como pares sustitutos . El iterador de cadenas itera sobre puntos de código.
UTF-16 en Wikipedia
fuente
Se trata del código detrás de los personajes. Algunos están codificados en dos bytes (UTF-16) y se interpretan
Array.from
como dos caracteres. Tengo que revisar la lista de los personajes:http://www.fileformat.info/info/charset/UTF-8/list.htm
http://www.fileformat.info/info/charset/UTF-16/list.htm
Para la función que muestra el código hexadecimal:
Javascript: cadena Unicode a hexadecimal
fuente