2012-06-21 12 views
27

Después de googlear frenéticamente, parece que no puedo encontrar una respuesta definitiva a una pregunta simple. Me disculpo si esta pregunta es respondida en alguna parte, pero si es así no pude encontrarla.Codificación de caracteres Javascript predeterminada?

Mientras escribía un método de encriptación en Javascript, me preguntaba qué carácter de codificación utilizaban mis cadenas, y por qué.

Entonces, ¿qué determina la codificación de caracteres en Javascript? ¿Es un estándar? Por el navegador? ¿Determinado por el encabezado de la solicitud HTTP? En la etiqueta <META> de HTML que lo abarca? El servidor que alimenta la página?

Por mis pruebas empíricas (cambiando las diferentes configuraciones, usando charCodeAt en un carácter suficientemente extraño y viendo con qué codificación coincide el valor) parece ser siempre UTF-8 o UTF-16, pero no estoy seguro por qué.

¡Gracias por la ayuda!

+3

Las cadenas de JavaScript siempre son UTF-16. – Pointy

+0

Supongo que esa es solo la respuesta. Por favor, ¿dónde está esto documentado? –

+0

Estoy tratando de identificarlo en el documento ECMA-262 ahora :-) – Pointy

Respuesta

22

Sección 8.4 de E262:

El tipo de cadena es el conjunto de todas las secuencias finitas ordenados de cero o más valores de número entero sin signo de 16 bits (“elementos”). El tipo String generalmente se usa para representar datos textuales en un programa ECMAScript en ejecución, en cuyo caso cada elemento en la Cadena se trata como un valor de unidad de código (ver Cláusula 6). Cada elemento se considera que ocupa una posición dentro de la secuencia. Estas posiciones están indexadas con enteros no negativos. El primer elemento (si lo hay) está en la posición 0, el siguiente elemento (si corresponde) en la posición 1, y así sucesivamente. La longitud de una Cadena es la cantidad de elementos (es decir, valores de 16 bits) dentro de ella. La cadena vacía tiene longitud cero y, por lo tanto, no contiene elementos.

Cuando una Cadena contiene datos de texto reales, cada elemento se considera una unidad de código UTF-16 única. Independientemente de que este sea el formato de almacenamiento real de una Cadena, los caracteres dentro de una Cadena se numeran por su posición inicial del elemento de la unidad de código como si estuvieran representados mediante UTF-16. Todas las operaciones en Strings (excepto que se indique lo contrario) las tratan como secuencias de enteros sin signo de 16 bits indiferenciados; no garantizan que la cadena resultante esté en forma normalizada, ni garantizan resultados sensibles al lenguaje.

Esa redacción es amable-weasely; parece significar que todo lo que se considera trata las cadenas como si cada carácter fuera un carácter UTF-16, pero al mismo tiempo, nada garantiza que todo sea válido.

edición — Para que quede claro, la intención es que las cadenas se componen de puntos de código UTF-16. En ES2015, la definición de "valor de cadena" incluye esta nota:

Un valor de cadena es un miembro del tipo Cadena. Cada valor entero en la secuencia generalmente representa una sola unidad de 16 bits de texto UTF-16. Sin embargo, ECMAScript no impone restricciones ni requisitos sobre los valores, excepto que deben ser enteros sin signo de 16 bits.

De modo que una cadena sigue siendo una cadena incluso cuando contiene valores que no funcionan como caracteres Unicode correctos.

+1

Documentación * y * weasley-redacción-traducciones! ¡Gracias! –

+3

Advertencia: cada elemento es una UTF-16 _code unit_. Aparentemente, los pares sustituidos contarían como dos caracteres en una cadena, aunque codifiquen un único carácter Unicode. – lanzz

9

No hay codificación de caracteres predeterminada para JavaScript como tal. Un programa de JavaScript es, en lo que respecta a las especificaciones, una secuencia de caracteres abstractos.Cuando se transmiten a través de una red, o simplemente se almacenan en una computadora, los caracteres abstractos deben codificarse de alguna manera, pero los mecanismos para ello no están controlados por el estándar ECMAScript.

La sección 6 de la norma ECMAScript usa UTF-16 como codificación de referencia, pero no la designa como predeterminada. El uso de UTF-16 como referencia es lógicamente innecesario (bastaría con referirse a los números Unicode), pero probablemente se asumió que ayudaba a las personas.

Este problema no se debe confundir con la interpretación de cadenas literales o cadenas en general. Un literal como 'Φ' debe estar en alguna codificación, junto con el resto del programa; esto puede ser cualquier codificación, pero después de que se haya resuelto la codificación, el literal se interpretará como un entero de acuerdo con el número Unicode del personaje.

Cuando se transmite un programa JavaScript como tal (como un "archivo JavaScript externo") a través de Internet, se aplica RFC 4329, tipos de medios de secuencias de comandos. La cláusula 4 define el mecanismo: Principalmente, se verifican los encabezados, como los encabezados HTTP, y se confiará en un parámetro charset. (En la práctica, los servidores web generalmente no especifican tal parámetro para los programas de JavaScript.) En segundo lugar, se aplica la detección de BOM. En su defecto, UTF-8 está implícito.

La primera parte del mecanismo es algo ambigua. Se podría interpretar como relacionado con el parámetro charset en un encabezado HTTP real solamente, o podría extenderse a los parámetros charset en los elementos script.

Si un programa JavaScript aparece como incrustado en HTML, ya sea a través de un elemento script o algún atributo de evento, entonces su codificación de caracteres es, por supuesto, la misma que la del documento HTML. La sección Specifying the character encoding de la especificación de HTML 4.01 define el mecanismo de resolución, en este orden: charset en el encabezado HTTP, charset en , charset en un enlace que se siguió para acceder al documento, y finalmente heurística (conjetura), que puede involucrar muchas cosas; cf. al complejo resolution mechanism in the HTML5 draft.

+2

Fascinante, pero para mí, mucho de esto suena como la forma en que se codificará el archivo Javascript, a diferencia de la forma en que Javascript maneja los literales de cadena en su código. ¿Estoy malentendido? –

+0

Mi respuesta fue de hecho sobre la codificación de caracteres de los programas de JavaScript. No existe una codificación de caracteres separada para los literales de JavaScript: 'abc' representa una secuencia de tres enteros de 16 bits, que son los números Unicode para a, b y c. Si parece que estaban de alguna manera "codificados en UTF-8" para que pueda obtener bytes UTF-8 al leer una cadena, entonces hay un malentendido. Pero para los caracteres Ascii, 'a' representa un entero de 16 bits que consiste en el byte de 8 bits para 'a' en Ascii y un byte cero, por lo que los datos pueden * verse * como codificados en UTF-8. –

Cuestiones relacionadas