Array.from
最初に引数のイテレータがある場合はそれを呼び出そうとし、文字列にはイテレータがあるため、を呼び出しますString.prototype[Symbol.iterator]
。プロトタイプメソッドがどのように機能するか調べてみましょう。それはここの仕様で説明されています:
- Oにしましょう RequireObjectCoercible(この値)。
- になろう ?ToString(O)。
- CreateStringIterator(S)を返します。
ルックアップCreateStringIterator
すると21.1.5.2.1 %StringIteratorPrototype%.next ( )
、最終的にに移動します。
- cpにしよう!CodePointAt(s、position)。
- resultStringを、インデックス位置のコードユニットで始まる、sから連続したcp。[[CodeUnitCount]]コードユニットを含むString値とします。
- O。[[StringNextIndex]]を位置+ cp。[[CodeUnitCount]]に設定します。
- CreateIterResultObject(resultString、false)を返します。
これCodeUnitCount
はあなたが興味を持っているものです。この番号はCodePointAtから取得されます。
- 最初に文字列内のインデックス位置のコード単位とします。
- cpを、最初の数値であるコードポイントとする。
最初が先行サロゲートまたは後続サロゲートでない場合、
a。レコードを返し{ [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }
ます。
最初が後続サロゲートまたは位置+ 1 =サイズの場合、
レコードを返す{ [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
。
2番目を文字列内のインデックス位置+ 1のコード単位とします。
2番目が後続の代理ではない場合、
a。レコードを返し{ [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }
ます。
cpを!UTF16DecodeSurrogatePair(1番目、2番目)。
レコードを返し{ [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }
ます。
したがって、で文字列を反復処理するArray.from
場合、問題の文字がサロゲートペアの開始である場合にのみ、CodeUnitCountが2を返します。サロゲートペアとして解釈される文字は次のとおりです。
このような操作は、0xD800から0xDBFFまでの範囲の数値(Unicode規格では先行サロゲートとして、またはより正式には高サロゲートコードユニットとして定義)のすべてのコードユニットと数値のすべてのコードユニットに特別な処理を適用します以下のルールを使用して、0xDC00から0xDFFFまでの範囲(後続サロゲートとして、またはより正式には低サロゲートコード単位として定義)。
षि
はサロゲートペアではありません:
console.log('षि'.charCodeAt()); // First character code: 2359, or 0x937
console.log('षि'.charCodeAt(1)); // Second character code: 2367, or 0x93F
しかし👍
の文字は次のとおりです。
console.log('👍'.charCodeAt()); // 55357, or 0xD83D
console.log('👍'.charCodeAt(1)); // 56397, or 0xDC4D
の最初の文字コード'👍'
は、16進数でD83Dであり、これは0xD800 to 0xDBFF
先行サロゲートの範囲内です。対照的に、の最初の文字コード'षि'
ははるかに低く、そうではありません。したがって、'षि'
分割されますが、分割され'👍'
ません。
षि
:二つの別々の文字で構成されष
、デーヴァナーガリー文字Ssaの、そしてि
、デーヴァナーガリー母音は私に署名。この順序で隣り合うと、2つの個別の文字で構成されているにもかかわらず、視覚的に1つの文字に視覚的に結合されます。
対照的に、の文字コードは、1つのグリフとしてまとめた場合に👍
のみ意味があります。どちらか一方のコードポイントを含む文字列をもう一方の文字列なしで使用しようとすると、意味のない記号が表示されます。
console.log('👍'[0]);
console.log('👍'[1]);