2016-07-13 8 views

Antwort

9

uses Javascript UTF-16 (source) Strings zu verwalten.

In UTF-16 gibt es 1.112.064 mögliche Zeichen. Nun wird jedes Zeichen code points dargestellt (*). In UTF-16 verwendet ein Codepunkt zwei Bytes (16 Bits), die gespeichert werden sollen. Dies bedeutet, dass Sie mit einem Codepunkt nur 65536 verschiedene Zeichen haben können.

Dies bedeutet, dass einige Zeichen mit zwei Codepunkten dargestellt werden müssen.

String.length() gibt die Anzahl der Codeeinheiten in der Zeichenfolge zurück, nicht die Anzahl der Zeichen.

MDN erklärt ganz gut, die Sache auf der Seite über String.length()

Diese Eigenschaft gibt die Anzahl der Codeeinheiten in der Zeichenkette. UTF-16, das von JavaScript verwendete Zeichenfolgenformat, verwendet eine einzelne 16-Bit-Codeeinheit, um die gebräuchlichsten Zeichen darzustellen. Für weniger häufig verwendete Zeichen müssen jedoch zwei Codeeinheiten verwendet werden stimmt nicht mit der tatsächlichen Anzahl der Zeichen in der Zeichenfolge überein.

(*): Eigentlich einige Zeichen im Bereich 010000 - 03FFFF und 040000 - 10FFFF kann bis zu 4 Bytes (32 Bits) pro Codepunkt verwenden, aber dies die Antwort nicht ändert : Einige Zeichen benötigen mehr als 2 Bytes, um dargestellt zu werden, also benötigen sie mehr als 1 Codepunkt.

Dies bedeutet, dass einige Zeichen, die mehr als 16 Bits benötigen, trotzdem eine Länge von 1 haben. Wie 0x03FFFF, braucht es 21 Bit, aber es nutzt nur eine Codeeinheit in UTF-16, so dass ihr String.length ist 1.

console.log(String.fromCharCode(0x03FFFF).length)

+0

Ich denke, nur ES2015 verwendet UTF-16 sowohl intern auf der Engine als auch auf der Sprachebene.ES5 codiert mit UCT-2 (mindestens auf der Sprachebene). Außerdem gibt es nur einen Codepunkt pro Zeichen (von 0x0 bis 0x10FFFF), der durch ein bis zwei Code-Einheiten repräsentiert wird. Da 'string.length' Code-Einheiten als einzelne Zeichen interpretiert, berechnet es falsche Ergebnisse für Zeichen außerhalb der Basic Multilingual Plane (BMP). – ftor

+0

@ LUH3417 afaik Auch ES5 verwendet UTF-16: 'Wenn eine Zeichenfolge tatsächliche Textdaten enthält, wird jedes Element als eine einzelne UTF-16-Codeeinheit betrachtet. Https://es5.github.io/ – rpadovani

+1

Oh, mein Fehler. Es heißt UCS-2 und ES5-Engines können beide verwenden (UCS-2/UTF-16). – ftor

5

Ich glaube rpadovani beantwortet Ihre „warum "Frage am besten, aber für eine Implementierung, die Ihnen eine richtige Glyphenanzahl in dieser Situation bringen wird, hat Lodash dieses Problem in ihrem toArray Modul geheftet.

Zum Beispiel

_.toArray('12').length; // --> 3 

Oder, wenn Sie ein paar beliebigen Zeichen aus einer Zeichenfolge klopfen wollen, können Sie das Array manipulieren und wieder zusammenzubringen, wie:

_.toArray("trimToEightGlyphs").splice(0,8).join(''); // --> 'trimToE' 
Verwandte Themen