41

JavaScript で暗号化メソッドを作成しているときに、自分の文字列がどの文字エンコーディングを使用しているのか、またその理由について疑問に思いました。

JavaScript の文字エンコーディングを決定するものは何ですか? それは標準ですか?ブラウザで?HTTP 要求のヘッダーによって決定されますか? それを囲むHTMLの<META>タグに?ページにフィードするサーバー?

私の経験的なテスト (さまざまな設定を変更してcharCodeAtから、十分に奇妙な文字を使用し、値が一致するエンコーディングを確認) では、常に UTF-8 または UTF-16 のように見えますが、その理由はわかりません。

必死にグーグルで調べた後、この単純な質問に対する決定的な答えを見つけることができなかったようです.

4

2 に答える 2

28

E262 のセクション 8.4:

String 型は、0 個以上の 16 ビット符号なし整数値 (「要素」) のすべての有限順序シーケンスのセットです。String 型は通常、実行中の ECMAScript プログラムでテキスト データを表すために使用されます。この場合、String の各要素はコード単位の値として扱われます (条項 6 を参照)。各要素は、シーケンス内の位置を占めていると見なされます。これらの位置は、負でない整数でインデックス付けされます。最初の要素 (存在する場合) は位置 0 にあり、次の要素 (存在する場合) は位置 1 にあり、以下同様です。String の長さは、その中の要素 (つまり、16 ビット値) の数です。空の String の長さはゼロであるため、要素は含まれません。

String に実際のテキスト データが含まれている場合、各要素は単一の UTF-16 コード単位と見なされます。これが文字列の実際の格納形式であるかどうかにかかわらず、文字列内の文字は、UTF-16 を使用して表されているかのように、最初のコード単位要素の位置によって番号が付けられます。文字列に対するすべての操作 (特に明記されている場合を除く) は、文字列を未微分 16 ビット符号なし整数のシーケンスとして扱います。結果の文字列が正規化された形式であることも、言語に依存した結果であることも保証されません。

その言い回しはちょっとイタズラです。カウントされるものはすべて、各文字が UTF-16 文字であるかのように文字列を扱うことを意味しているように見えますが、同時に、すべてが有効であることを保証するものは何もありません。

明確にするために、文字列は UTF-16 コード ポイントで構成されることを意図しています。ES2015では、「文字列値」の定義に次の注記が含まれています。

String 値は、String 型のメンバーです。シーケンス内の各整数値は、通常、UTF-16 テキストの単一の 16 ビット単位を表します。ただし、ECMAScript では、値が 16 ビットの符号なし整数でなければならないことを除いて、値に制限や要件はありません。

したがって、正しい Unicode 文字として機能しない値が含まれている場合でも、文字列は文字列のままです。

于 2012-06-21T15:17:47.927 に答える
13

JavaScript自体のデフォルトの文字エンコードはありません。JavaScriptプログラムは、仕様に関する限り、一連の抽象文字です。ネットワークを介して送信する場合、または単にコンピュータに保存する場合、抽象文字は何らかの方法でエンコードする必要がありますが、そのメカニズムはECMAScript標準によって制御されていません。

ECMAScript標準のセクション6は、参照エンコーディングとしてUTF-16を使用していますが、デフォルトとして指定していません。参照としてUTF-16を使用することは論理的に不要ですが(Unicode番号を参照することで十分です)、おそらく人々を助けると想定されていました。

この問題は、文字列リテラルまたは文字列一般の解釈と混同しないでください。'Φ'のようなリテラルは、プログラムの残りの部分と一緒に、いくつかのエンコーディングである必要があります。これは任意のエンコーディングにすることができますが、エンコーディングが解決された後、リテラルは文字のUnicode番号に従って整数として解釈されます。

JavaScriptプログラムがインターネットを介して(「外部JavaScriptファイル」として)そのまま送信される場合、RFC 4329、スクリプトメディアタイプが適用されます。条項4は、メカニズムを定義します。主に、HTTPヘッダーなどのヘッダーがチェックされ、charsetそこにあるパラメーターが信頼されます。(実際には、Webサーバーは通常JavaScriptプログラムにそのようなパラメーターを指定しません。)次に、BOM検出が適用されます。これに失敗すると、UTF-8が暗示されます。

メカニズムの最初の部分はややあいまいです。これは、実際のHTTPヘッダーのパラメーターのみに関連していると解釈される場合もあれば、要素のパラメーターにcharset拡張される場合もあります。charsetscript

JavaScriptプログラムが要素または何らかのイベント属性を介してHTMLに埋め込まれているように見える場合、scriptその文字エンコードはもちろんHTMLドキュメントの文字エンコードと同じです。セクションHTML4.01仕様の文字エンコードを指定するcharsetと、解決メカニズムが次の順序で定義されます。HTTPヘッダー、charsetmetacharsetドキュメントにアクセスするためにたどられたリンクで、最後にヒューリスティック(推測)。これには多くのことが関係する可能性があります。cf. HTML5ドラフトの複雑な解決メカニズムに。

于 2012-06-21T16:39:17.060 に答える