web-dev-qa-db-ja.com

デフォルトのJavaScript文字エンコーディング?

いくつかの必死のグーグルの後、私は単純な質問に対する決定的な答えを見つけることができないようです。この質問に対する回答がどこかである場合はお詫び申し上げますが、回答できない場合は見つかりませんでした。

Javascriptで暗号化メソッドを作成しているときに、文字列で使用されている文字エンコーディングとその理由を知りました。

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

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

助けてくれてありがとう!

37
Nick

E262のセクション8.4:

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

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

その言葉遣いは一種の簡単なものです。これは、カウントするすべてのものが文字列を各文字がUTF-16文字であるかのように扱うことを意味するようですが、同時に、すべてが有効であることを保証するものは何もありません。

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

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

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

27
Pointy

そのため、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パラメーターにのみ関連すると解釈される場合や、charset要素のscriptパラメーターに拡張される場合があります。

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

12