Array.fromZuerst 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 CreateStringIteratorSie 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 CodeUnitCountist, 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.fromdurchlaufen, 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 0xDBFFder 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]);