2012-06-21 3 views
27

광란 인터넷 검색을 한 후 간단한 질문에 대한 결정적인 대답을 찾을 수 없습니다. 이 질문이 어딘가에있는 것이면 사과드립니다. 그렇다면 찾을 수 없습니다.기본 Javascript 문자 인코딩?

자바 스크립트에서 암호화 방법을 쓰는 동안 필자는 필자의 문자열이 어떤 문자 인코딩을 사용했는지 궁금해했습니다.

그렇다면 Javascript에서 문자 인코딩을 결정하는 것은 무엇입니까? 표준인가? 브라우저로? HTTP 요청의 헤더에 의해 결정됩니까? 그것을 포위하는 HTML의 <META> 꼬리표에서? 페이지를 공급하는 서버?

내 경험적 테스트 (다른 ​​설정을 변경하고 충분히 이상한 문자로 charCodeAt을 사용하고 어떤 인코딩 값과 일치하는지 확인)을 통해 UTF-8 또는 UTF-16 인 것처럼 보입니다. 그러나 확실하지 않습니다. 이유가입니다.

도움 주셔서 감사합니다.

+3

JavaScript 문자열은 항상 UTF-16입니다. – Pointy

+0

그때 그 대답 일 것 같네요. 제발,이 문서화 된 곳은 어디입니까? –

+0

ECMA-262 문서에서 정확히 알아 내려고 노력하고 있습니다 :-) – Pointy

답변

22

제 E262 8.4 :

문자열 타입 0 이상의 16 비트 부호없는 정수 값 ("요소")의 모든 유한 한 명령 시퀀스의 집합이다. 문자열 유형은 일반적으로 실행중인 ECMAScript 프로그램에서 텍스트 데이터를 나타 내기 위해 사용되며,이 경우 문자열의 각 요소는 코드 단위 값으로 취급됩니다 (6 절 참조). 각 요소는 시퀀스 내의 위치를 ​​차지하는 것으로 간주됩니다. 이러한 위치는 음수가 아닌 정수로 인덱싱됩니다. 최초의 요소가있는 경우는 그 위치가 0, 다음의 요소가있는 경우는 1의 위치에 있습니다. String의 길이는 그 안에있는 요소 (즉, 16 비트 값)의 수입니다. 하늘의 String는 길이가 0이며, 따라서 요소를 포함하지 않습니다.

문자열에 실제 텍스트 데이터가 들어있는 경우 각 요소는 단일 UTF-16 코드 단위로 간주됩니다. 이것이 String의 실제 저장 형식인지 여부에 관계없이 String 내의 문자는 UTF-16을 사용하여 표현 된 것처럼 초기 코드 단위 요소 위치에 의해 번호가 매겨집니다. 문자열에 대한 모든 연산 (달리 명시된 경우 제외)은이를 구분되지 않은 16 비트 부호없는 정수의 시퀀스로 처리합니다. 결과 String이 정규화 된 형식인지 또는 언어에 민감한 결과를 보장하는지 여부는 보장하지 않습니다.

그 말씨는 일종의 것입니다. 그것은 모든 문자가 UTF-16 문자 인 것처럼 문자열을 취급하지만 동시에 모든 것이 유효하다는 것을 보장하지 않는다는 것을 의미합니다.

편집 —이 명확하게하려면 의도 문자열은 UTF-16 코드 포인트로 구성되어 있다는 점이다. ES2015에서 "문자열 값"의 정의에는 다음 내용이 포함됩니다.

문자열 값은 String 유형의 멤버입니다. 시퀀스의 각 정수 값은 일반적으로 UTF-16 텍스트의 단일 16 비트 단위를 나타냅니다. 그러나 ECMAScript는 16 비트 부호없는 정수 여야한다는 점을 제외하고는 값에 제한이나 요구 사항을 두지 않습니다.

올바른 유니 코드 문자로 작동하지 않는 값이 포함되어 있어도 문자열은 여전히 ​​문자열입니다.

+1

문서 * 및 * weasley-wording-translations! 감사! –

+3

주의 사항 : 각 요소는 UTF-16 _code 단위 _입니다. 분명히 서로 게이트 쌍은 단일 유니 코드 문자를 인코딩하더라도 문자열에서 두 문자로 계산됩니다. – lanzz

9

JavaScript에는 기본 문자 인코딩이 없습니다. JavaScript 프로그램은 사양과 관련하여 추상 문자 시퀀스입니다.네트워크를 통해 전송되거나 컴퓨터에 저장된 경우 추상 문자는 어떻게 든 인코딩되어야하지만 이에 대한 메커니즘은 ECMAScript 표준에 의해 제어되지 않습니다.

ECMAScript 표준의 섹션 6은 참조 인코딩으로 UTF-16을 사용하지만 기본값으로 지정하지 않습니다. 참고로 UTF-16을 사용하는 것은 논리적으로 불필요합니다 (유니 코드 번호를 언급하는 것으로 충분할 것입니다). 그러나 아마 사람들을 돕는 것으로 가정되었습니다.

이 문제는 일반적으로 문자열 리터럴이나 문자열 해석과 혼동되어서는 안됩니다. 'Φ'와 같은 리터럴은 프로그램의 나머지 부분과 함께 일부 인코딩에 있어야합니다. 이것은 임의의 인코딩이 될 수 있지만, 인코딩이 해결 된 후에는 리터럴이 문자의 유니 코드 번호에 따라 정수로 해석됩니다.

인터넷을 통해 ("외부 JavaScript 파일"처럼) JavaScript 프로그램이 전송되면 RFC 4329, 스크립팅 미디어 유형이 적용됩니다. 4 절에서는 메커니즘을 정의합니다. 주로 HTTP 헤더와 같은 헤더가 확인되고 charset 매개 변수가 신뢰됩니다. 실제로 웹 서버는 일반적으로 JavaScript 프로그램에 대해 이러한 매개 변수를 지정하지 않습니다. 둘째, BOM 감지가 적용됩니다. 실패하면 UTF-8이 암시됩니다.

메커니즘의 첫 번째 부분은 다소 모호합니다. 실제 HTTP 헤더에서만 charset 매개 변수와 관련된 것으로 해석되거나 charset 매개 변수 script 요소로 확장 될 수 있습니다.

script 요소 또는 이벤트 속성을 통해 JavaScript 프로그램이 HTML에 포함 된 것으로 나타나면 문자 인코딩은 물론 HTML 문서의 문자 인코딩과 동일합니다. HTTP 헤더의 charset, charsetmeta, charset의 문서에 액세스하기위한 링크, 그리고 마지막으로 휴리스틱 (추측)과 같은 여러 메커니즘이 정의되어 있습니다 (HTML 4.01 사양의 Specifying the character encoding 섹션 참조). 참조 복잡한 resolution mechanism in the HTML5 draft.

+2

매혹적인 -하지만 나에게 이것은 Javascript가 코드에서 문자열 리터럴을 처리하는 방식과는 달리 실제 Javascript 파일 자체가 인코딩되는 방식과 비슷합니다. 내가 오해하고 있니? –

+0

제 대답은 실제로 JavaScript 프로그램의 문자 인코딩에 관한 것입니다. JavaScript 리터럴에는 별도의 문자 인코딩이 없습니다. 'abc'은 a, b 및 c의 유니 코드 숫자 인 세 개의 16 비트 정수 시퀀스를 나타냅니다. 문자열을 읽을 때 UTF-8 바이트를 얻을 수 있도록 어떻게 든 "UTF-8로 인코딩 된"것처럼 보이면 약간의 오해가 있습니다. 그러나 Ascii 문자의 경우 'a'는 Ascii의 'a'에 대한 8 비트 바이트와 0 바이트로 구성된 16 비트 정수를 나타내므로 데이터는 UTF-8로 인코딩 된 것처럼 보일 수 있습니다. –