2012-06-21 10 views
27

Nach etwas hektischem Googeln kann ich keine schlüssige Antwort auf eine einfache Frage finden. Ich entschuldige mich, wenn diese Frage irgendwo beantwortet wird, aber wenn ich sie nicht finden könnte.Standard Javascript Zeichencodierung?

Während ich eine Verschlüsselungsmethode in Javascript geschrieben habe, habe ich mich gefragt, welche Zeichenkodierung meine Zeichenketten verwenden und warum.

Also: Was bestimmt die Zeichencodierung in Javascript? Ist es ein Standard? Durch den Browser? Wird durch den Header der HTTP-Anfrage bestimmt? In der <META> HTML-Tag, die es umfasst? Der Server, der die Seite einspeist?

Durch meine empirischen Tests (verschiedene Einstellungen ändern, dann charCodeAt auf ein ausreichend seltsames Zeichen verwenden und sehen, welche Kodierung der Wert übereinstimmt) scheint es immer UTF-8 oder UTF-16 zu sein, aber ich bin mir nicht sicher warum.

Danke für die Hilfe!

+3

JavaScript-Zeichenfolgen sind immer UTF-16. – Pointy

+0

Ich denke, das ist dann nur die Antwort. Bitte, wo ist das dokumentiert? –

+0

Ich versuche es jetzt im Dokument ECMA-262 zu lokalisieren :-) – Pointy

Antwort

22

Abschnitt 8.4 von E262:

Der String-Typ ist die Menge aller endlichen geordneten Sequenzen von null oder mehr 16-Bit Integer ohne Vorzeichen-Werte („Elemente“). Der String-Typ wird im Allgemeinen verwendet, um Textdaten in einem laufenden ECMAScript-Programm darzustellen. In diesem Fall wird jedes Element im String als Code-Einheitswert behandelt (siehe Abschnitt 6). Jedes Element wird als eine Position innerhalb der Sequenz besetzend angesehen. Diese Positionen sind mit nichtnegativen ganzen Zahlen indiziert. Das erste Element (falls vorhanden) befindet sich an Position 0, das nächste Element (falls vorhanden) an Position 1 und so weiter. Die Länge eines Strings ist die Anzahl der Elemente (d. H. 16-Bit-Werte) innerhalb des Strings. Der leere String hat die Länge Null und enthält daher keine Elemente.

Wenn ein String tatsächliche Textdaten enthält, wird jedes Element als eine einzelne UTF-16-Codeeinheit betrachtet. Unabhängig davon, ob dies das tatsächliche Speicherformat eines Strings ist oder nicht, werden die Zeichen in einem String durch ihre ursprüngliche Position in der Codeeinheit nummeriert, als ob sie mit UTF-16 dargestellt würden. Alle Operationen an Strings (wenn nicht anders angegeben) behandeln sie als Sequenzen von undifferenzierten 16-Bit-Ganzzahlen ohne Vorzeichen; Sie stellen weder sicher, dass der resultierende String normalisiert ist, noch gewährleisten sie sprachsensitive Ergebnisse.

Diese Formulierung ist irgendwie weasely; es scheint zu bedeuten, dass alles, was zählt, Strings so behandelt, als ob jedes Zeichen ein UTF-16-Zeichen wäre, aber gleichzeitig stellt nichts sicher, dass alles gültig sein wird.

bearbeiten — klar zu sein, die Absicht ist, dass Zeichenketten von UTF-16-Codepunkte bestehen. In ES2015 enthält die Definition von "Zeichenfolgenwert" diese Notiz:

Ein String-Wert ist ein Mitglied des String-Typs. Jeder Integer-Wert in der Sequenz repräsentiert normalerweise eine einzelne 16-Bit-Einheit von UTF-16-Text. ECMAScript stellt jedoch keine Einschränkungen oder Anforderungen an die Werte, außer dass sie 16-Bit-Ganzzahlen ohne Vorzeichen sein müssen.

Also eine Zeichenfolge ist immer noch eine Zeichenfolge, auch wenn es Werte enthält, die nicht als richtige Unicode-Zeichen funktionieren.

+1

Dokumentation * und * Weasley-Wording-Übersetzungen! Vielen Dank! –

+3

Vorbehalt: Jedes Element ist eine UTF-16 _code unit_. Anscheinend werden Ersatzpaare als zwei Zeichen in einer Zeichenfolge gezählt, obwohl sie ein einzelnes Unicode-Zeichen codieren. – lanzz

9

Es gibt keine Standardzeichencodierung für JavaScript als solches. Ein JavaScript-Programm ist, soweit es die Spezifikationen betrifft, eine Folge von abstrakten Zeichen.Wenn die abstrakten Zeichen über ein Netzwerk übertragen oder nur auf einem Computer gespeichert werden, müssen sie irgendwie codiert werden, aber die Mechanismen dafür werden nicht vom ECMAScript-Standard gesteuert.

In Abschnitt 6 des Standards ECMAScript wird UTF-16 als Referenzcodierung verwendet, jedoch nicht als Standard. Die Verwendung von UTF-16 als Referenz ist logisch unnötig (es würde ausreichen, auf Unicode-Nummern zu verweisen), aber es wurde wahrscheinlich angenommen, dass es Leuten hilft.

Dieses Problem sollte nicht mit der Interpretation von String-Literalen oder Zeichenfolgen im Allgemeinen verwechselt werden. Ein Literal wie 'Φ' muss zusammen mit dem Rest des Programms codiert werden; Dies kann eine beliebige Codierung sein, aber nachdem die Codierung aufgelöst wurde, wird das Literal gemäß der Unicode-Nummer des Zeichens als Ganzzahl interpretiert.

Wenn ein JavaScript-Programm als solches (als "externe JavaScript-Datei") über das Internet übertragen wird, gilt RFC 4329, Scripting Media Types. Abschnitt 4 definiert den Mechanismus: In erster Linie werden Header wie HTTP-Header überprüft, und auf einen charset Parameter wird vertraut. (In der Praxis geben Web-Server normalerweise keinen solchen Parameter für JavaScript-Programme an.) Zweitens wird die Stücklistenerkennung angewendet. Fehlt das, ist UTF-8 impliziert.

Der erste Teil des Mechanismus ist etwas mehrdeutig. Es könnte so interpretiert werden, dass es sich auf charset Parameter in einem tatsächlichen HTTP-Header bezieht, oder möglicherweise auf charset Parameter in script Elemente erweitert werden.

Wenn ein JavaScript-Programm als eingebettet in HTML angezeigt wird, entweder über ein script Element oder ein Ereignisattribut, dann ist seine Zeichencodierung natürlich dieselbe wie die des HTML-Dokuments. Abschnitt Specifying the character encoding der Spezifikation HTML 4.01 definiert den Auflösungsmechanismus in dieser Reihenfolge: charset in HTTP-Header, charset in meta, charset in einem Link, der gefolgt wurde, um auf das Dokument zugreifen, und schließlich Heuristiken (Raten), die viele Dinge beteiligt sein können; vgl. zum Komplex resolution mechanism in the HTML5 draft.

+2

Faszinierend - aber für mich klingt vieles wie die Art und Weise, wie die eigentliche Javascript-Datei selbst kodiert wird, im Gegensatz zu der Art und Weise, wie JavaScript String-Literale in seinem Code verarbeitet. Missverständnis ich? –

+0

Meine Antwort war in der Tat über Zeichencodierung von JavaScript-Programmen. Es gibt keine separate Zeichenkodierung für JavaScript-Literale: "abc" steht für eine Folge von drei 16-Bit-Ganzzahlen, die die Unicode-Zahlen für a, b und c sind. Wenn es so aussieht, als wären sie irgendwie "UTF-8-codiert", so dass Sie beim Lesen einer Zeichenfolge UTF-8-Bytes erhalten würden, dann gibt es ein Missverständnis. Aber für Ascii-Zeichen steht "a" für eine 16-Bit-Ganzzahl, die aus dem 8-Bit-Byte für "a" in Ascii und einem Null-Byte besteht, so dass die Daten * wie UTF-8-codiert aussehen können. –