Array.from
Zuerst wird versucht, den Iterator des Arguments aufzurufen, falls vorhanden, und Zeichenfolgen haben Iteratoren. Daher wird er aufgerufen String.prototype[Symbol.iterator]
. Schauen wir uns also an, wie die Prototypmethode funktioniert. Es ist in der Spezifikation hier beschrieben :
- Lass O sein? RequireObjectCoercible (dieser Wert).
- Lass uns sein ? ToString (O).
- Geben Sie CreateStringIterator (S) zurück.
Wenn CreateStringIterator
Sie nach oben schauen, gelangen Sie schließlich zu 21.1.5.2.1 %StringIteratorPrototype%.next ( )
:
- Lass cp sein! CodePointAt (s, Position).
- Sei resultString der String-Wert, der cp enthält. [[CodeUnitCount]] aufeinanderfolgende Codeeinheiten von s beginnend mit der Codeeinheit an der Indexposition.
- Setzen Sie O. [[StringNextIndex]] auf Position + cp. [[CodeUnitCount]].
- Rückgabe CreateIterResultObject (resultString, false).
Das CodeUnitCount
ist, woran Sie interessiert sind. Diese Nummer stammt von CodePointAt :
- Sei zunächst die Codeeinheit an der Indexposition innerhalb der Zeichenfolge.
- Sei cp der Codepunkt, dessen numerischer Wert der von first ist.
Wenn zuerst kein führender oder nachfolgender Ersatz ist, dann
ein. Geben Sie den Datensatz zurück { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }
.
Wenn zuerst ein nachfolgender Ersatz oder eine Position + 1 = Größe ist, dann
a.Rückgabe der Aufzeichnung { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
.
Als zweites sei die Codeeinheit an der Indexposition + 1 innerhalb der Zeichenfolge.
Wenn der zweite kein nachfolgender Ersatz ist, dann
ein. Geben Sie den Datensatz zurück { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
.
Setze cp auf! UTF16DecodeSurrogatePair (erste, zweite).
Geben Sie den Datensatz zurück { [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }
.
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 :
Solche Operationen wenden eine Sonderbehandlung für jede Codeeinheit mit einem numerischen Wert im Inklusivbereich 0xD800 bis 0xDBFF (definiert durch den Unicode-Standard als führender Ersatz oder formeller als Codeeinheit mit hohem Ersatz ) und jede Codeeinheit mit einem numerischen Wert an im Inklusivbereich 0xDC00 bis 0xDFFF (definiert als nachfolgender Ersatz oder formeller als Codeeinheit mit niedrigem Ersatz) unter Verwendung der folgenden Regeln:
षि
ist kein Ersatzpaar:
console.log('षि'.charCodeAt()); // First character code: 2359, or 0x937
console.log('षि'.charCodeAt(1)); // Second character code: 2367, or 0x93F
Aber 👍
die Charaktere sind:
console.log('👍'.charCodeAt()); // 55357, or 0xD83D
console.log('👍'.charCodeAt(1)); // 56397, or 0xDC4D
Der erste Zeichencode von '👍'
ist in hexadezimaler Form D83D, was im Bereich 0xD800 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:
console.log('👍'[0]);
console.log('👍'[1]);