2012-06-21 2 views
27

После некоторого безумного Googling я не могу найти окончательного ответа на простой вопрос. Я прошу прощения, если на этот вопрос задан вопрос, но если так, я не смог его найти.По умолчанию Javascript кодировка символов?

При написании метода шифрования в Javascript мне стало интересно, какой символ кодирует мои строки, и почему.

Итак: что определяет кодировку символов в Javascript? Это стандарт? В браузере? Определяется заголовком HTTP-запроса? В теге <META> HTML, который его охватывает? Сервер, который загружает страницу?

По моим эмпирическим испытаниям (изменение разных настроек, а затем использование charCodeAt на достаточно странном символе и видя, какая кодировка соответствует значению), он всегда выглядит как UTF-8 или UTF-16, но я не уверен почему.

Спасибо за помощь!

+3

Строки JavaScript всегда UTF-16. – Pointy

+0

Я думаю, это только ответ. Пожалуйста, где это задокументировано? –

+0

Я пытаюсь точно определить его в документе ECMA-262 :-) – Pointy

ответ

22

Раздел 8.4 E262:

Тип Строка представляет собой множество всех конечных упорядоченных последовательностей из нуля или более 16-битных беззнаковых целых значений («элементы»). Тип String обычно используется для представления текстовых данных в запущенной программе ECMAScript, и в этом случае каждый элемент в String рассматривается как значение кода (см. Раздел 6). Каждый элемент считается занимающим позицию в последовательности. Эти позиции индексируются с неотрицательными целыми числами. Первый элемент (если есть) находится в позиции 0, следующий элемент (если есть) в позиции 1 и т. Д. Длина строки - это количество элементов (то есть 16-битных значений) внутри нее. Пустая строка имеет длину ноль и поэтому не содержит элементов.

Когда строка содержит фактические текстовые данные, каждый элемент считается единым блоком кода UTF-16. Независимо от того, является ли это фактическим форматом хранения строки, символы внутри строки нумеруются по их исходной позиции элемента кода, как если бы они были представлены с использованием UTF-16. Все операции над строками (кроме как указано иначе) рассматривают их как последовательности недифференцированных 16-разрядных целых без знака; они не гарантируют, что результирующая строка находится в нормализованной форме, и они не гарантируют результаты, чувствительные к языку.

Эта формулировка носит своеобразный характер; это означает, что все, что считается, обрабатывает строки так, как если бы каждый символ был символом UTF-16, но в то же время ничто не гарантирует, что все это будет действительным.

редактировать — быть ясен, намерения что строки состоят из UTF-16 кодовых. В ES2015 определение «строковое значение» включает в себя следующее примечание:

Значение строки является членом типа String. Каждое целое значение в последовательности обычно представляет собой одну 16-битную единицу текста UTF-16. Однако ECMAScript не устанавливает никаких ограничений или требований к значениям, за исключением того, что они должны быть 16-разрядными целыми без знака.

Таким образом, строка по-прежнему является строкой, даже если она содержит значения, которые не работают как правильные символы юникода.

+1

Документация * и * weasley-wording-translations! Благодаря! –

+3

Предостережение: каждый элемент является UTF-16 _code unit_. По-видимому, суррогатные пары считались бы двумя символами в строке, хотя они кодировали один символ Юникода. – lanzz

9

Для JavaScript не существует кодировки символов по умолчанию. Программа JavaScript, в отношении спецификаций, представляет собой последовательность абстрактных символов.При передаче по сети или просто хранении на компьютере абстрактные символы должны каким-то образом кодироваться, но механизмы для этого не контролируются стандартом ECMAScript.

Раздел 6 стандарта ECMAScript использует UTF-16 в качестве эталонного кодирования, но не обозначает его по умолчанию. Использование UTF-16 в качестве ссылки логически не нужно (достаточно было бы назвать номера Юникода), но, вероятно, предполагалось, что это поможет людям.

Эта проблема не следует путать с интерпретацией строковых литералов или строк в целом. Буква, подобная «Φ», должна быть в некоторой кодировке вместе с остальной частью программы; это может быть любая кодировка, но после того, как кодировка была разрешена, литерал будет интерпретироваться как целое число в соответствии с номером Unicode символа.

Когда программа JavaScript передается как таковая (как «внешний файл JavaScript») через Интернет, применяется RFC 4329, Scripting Media Types. Параграф 4 определяет механизм: в первую очередь проверяются заголовки, такие как HTTP-заголовки, и параметр charset, которому будет доверять. (На практике веб-серверы обычно не указывают такой параметр для программ JavaScript.) Во-вторых, применяется обнаружение спецификации. В противном случае подразумевается UTF-8.

Первая часть механизма несколько неоднозначна. Он может быть интерпретирован как относящийся к параметру charset только в фактическом HTTP-заголовке или может быть расширен до charset параметров в script элементах.

Если программа JavaScript отображается как встроенная в HTML, либо через элемент script, либо какой-либо атрибут события, то его кодировка символов, конечно же, совпадает с кодировкой HTML-документа. Раздел Specifying the character encoding спецификации HTML 4.01 определяет механизм разрешения в следующем порядке: charset в заголовке HTTP, charset в meta, charset в ссылке, которая была использована для доступа к документу, и, наконец, эвристики (догадки), которые могут включать в себя много вещей; ср к комплексу resolution mechanism in the HTML5 draft.

+2

Увлекательный - но для меня это очень похоже на то, как будет зашифрован сам файл Javascript, в отличие от того, как Javascript обрабатывает строковые литералы в своем коде. Я не понимаю? –

+0

Мой ответ был действительно о кодировке символов программ JavaScript. Для букв JavaScript нет отдельной кодировки символов: «abc» обозначает последовательность из трех 16-битных целых чисел, которые являются номерами Unicode для a, b и c. Если это похоже на то, что они были как-то «кодированы UTF-8», так что вы будете получать байты UTF-8 при чтении строки, тогда есть некоторые недоразумения. Но для символов Ascii «a» означает 16-разрядное целое число, состоящее из 8-битного байта для «a» в Ascii и нулевого байта, поэтому данные могут * выглядеть *, как кодированные UTF-8. –

Смежные вопросы