Ich habe mit JS herumgespielt und kann nicht herausfinden, wie JS entscheidet, welche Elemente bei der Verwendung zum erstellten Array hinzugefügt werden sollen Array.from()
. Das folgende Emoji 👍 hat beispielsweise eine length
2, da es aus zwei Codepunkten besteht. Array.from()
Diese beiden Codepunkte werden jedoch als eins behandelt, wodurch ein Array mit einem Element erhalten wird:
const emoji = '👍';
console.log(Array.from(emoji)); // Output: ["👍"]
Einige andere Zeichen haben jedoch auch zwei Codepunkte wie dieses Zeichen षि
(hat auch einen .length
von 2). Jedoch Array.from
nicht „Gruppe“ dieses Zeichen und stattdessen erzeugt zwei Elemente:
const str = 'षि';
console.log(Array.from(str)); // Output: ["ष", "ि"]
Meine Frage ist: Was bestimmt, ob das Zeichen aufgeteilt wird (wie in Beispiel zwei) oder als ein einzelnes Element behandelt wird (wie in Beispiel eins), wenn das Zeichen aus zwei Codepunkten besteht?
quelle
षि
ist 2 separate Zeichenlength
. Iteratoren oderSet
funktionieren sogar nicht damitAntworten:
Array.from
Zuerst wird versucht, den Iterator des Arguments aufzurufen, falls vorhanden, und Zeichenfolgen haben Iteratoren. Daher wird er aufgerufenString.prototype[Symbol.iterator]
. Schauen wir uns also an, wie die Prototypmethode funktioniert. Es ist in der Spezifikation hier beschrieben :Wenn
CreateStringIterator
Sie nach oben schauen, gelangen Sie schließlich zu21.1.5.2.1 %StringIteratorPrototype%.next ( )
:Das
CodeUnitCount
ist, woran Sie interessiert sind. Diese Nummer stammt von CodePointAt :Wenn Sie also eine Zeichenfolge mit
Array.from
durchlaufen, wird nur dann ein CodeUnitCount von 2 zurückgegeben, wenn das betreffende Zeichen der Anfang eines Ersatzpaars ist. Zeichen, die als Ersatzpaare interpretiert werden, werden hier beschrieben :षि
ist kein Ersatzpaar:Aber
👍
die Charaktere sind:Der erste Zeichencode von
'👍'
ist in hexadezimaler Form D83D, was im Bereich0xD800 to 0xDBFF
der führenden Surrogate liegt. Im Gegensatz dazu ist der erste Zeichencode von'षि'
viel niedriger und nicht. Das'षि'
wird also aufgeteilt,'👍'
tut es aber nicht.षि
besteht aus zwei getrennten Zeichen:ष
, Devanagari Brief Ssa undि
, Devanagari Vowel Zeichen I . Wenn sie in dieser Reihenfolge nebeneinander stehen, werden sie visuell grafisch zu einem einzigen Zeichen kombiniert, obwohl sie aus zwei separaten Zeichen bestehen.Im Gegensatz dazu sind die Zeichencodes von
👍
nur dann sinnvoll, wenn sie als einzelne Glyphe zusammengefasst sind. Wenn Sie versuchen, eine Zeichenfolge mit einem der Codepunkte ohne den anderen zu verwenden, erhalten Sie ein Unsinnssymbol:quelle
षि
handelt es sich tatsächlich um zwei Zeichen mit unterschiedlichen Codepunkten, die zu einem einzigen kombiniert werden Glyphe (ein abstraktes Zeichen, wie es vom Menschen verstanden wird). Dies steht im Gegensatz zum👍
Emoji, das an und für sich ein vollständiges Zeichen ist, obwohl sein Codepunkt hoch genug ist, dass es in ein Ersatzpaar aufgeteilt werden muss. Ich glaube zu klären, dass diese (ansonsten wertvolle) Antwort viel helfen könnte.UTF-16 (die für Zeichenfolgen in js verwendete Codierung) verwendet 16-Bit-Einheiten. Jeder Unicode, der mit 15 Bit dargestellt werden kann, wird als ein Codepunkt dargestellt, alles andere als zwei, sogenannte Ersatzpaare . Der Iterator von Zeichenfolgen iteriert über Codepunkte.
UTF-16 auf Wikipedia
quelle
Es geht nur um den Code hinter den Zeichen. Einige sind in zwei Bytes (UTF-16) codiert und werden
Array.from
als zwei Zeichen interpretiert . Muss die Liste der Charaktere überprüfen:http://www.fileformat.info/info/charset/UTF-8/list.htm
http://www.fileformat.info/info/charset/UTF-16/list.htm
Für die Funktion, die den Hex-Code anzeigt:
Javascript: Unicode-Zeichenfolge zu hex
quelle