자바스크립트/모던 자바스크립트

모던 자바스크립트, UTF-16 이슈 해결에 관련된 문자열 함수

Jake Seo 2023. 3. 11. 19:41

UTF-16 과 관련된 변화 사항

코드 포인트 이스케이프 시퀀스 (Code point escape sequence)

  • 유니코드 6.0 부터 이모지가 유니코드에 추가되었다.
  • 이모지는 8비트의 코드 유닛 2개로 표현된다.
  • 코드 포인트 이스케이프 시퀀스는 2개의 코드 유닛을 이용한 문자를 작성하기 위해선 번거로웠던 부분을 해결한다.
console.log("\uD83D\uDE0A"); // 😊
console.log("\u{1F60A}"); // 😊

String.fromCodePoint()

  • 코드 포인트를 숫자로 전달받아 해당하는 유니코드 문자열로 변경해준다.
  • 함수 버전의 코드 포인트 변환기이다.
console.log(String.fromCodePoint(0x1f60a)); // 😊
console.log(String.fromCodePoint(128522)); // 😊

String.prototype.codePointAt()

  • 문자열의 n 번째 인덱스에 있는 문자의 코드 포인트를 얻는다.
"😊".codePointAt(0); // 128522
"😊".codePointAt(0).toString(16); // '1f60a'

자바스크립트 UTF-16 문자열 반복 관련 이슈와 for-of

const emoji = "😊";
console.log(emoji.length); // 2
console.log(emoji[0]); // '\uD83D'
console.log(emoji[1]); // '\uDE0A'
  • 문자 1개가 4바이트를 차지하는 경우, 문자는 1개인데 길이가 2로 나온다.
  • 2바이트짜리 코드 유닛 2개가 합쳐져 하나의 문자를 만들어내야 하는데, 각각을 따로 보았기 때문이다.
  • 문자를 1개씩 출력하고 싶다고 for 문을 이용하면 아래와 같은 상황을 겪게 된다.
const emoji = "😊";

for (let i = 0; i < emoji.length; i++) {
  console.log(emoji[i]);
}
// �
// �
  • 각각의 코드 유닛은 유니코드에서 매칭되는 글자가 없기 때문에 적절히 표현되지 않는다.
  • 이럴 때는 for-of 를 사용하면 적절히 처리할 수 있다.
const emoji = "😊";

for (const c of emoji) {
  console.log(c);
}
// 😊

UTF-16 문자열 쪼개기 (split) 이슈와 Array.from()

  • 위에서 설명한 문자열 반복 이슈와 동일하게 문자열을 쪼갤 때도 동일한 문제가 발생한다.
const emoji = "😊";

console.log(emoji.split("")); //  ['\uD83D', '\uDE0A']
  • Array.from() 메서드를 이용해 이를 해결할 수 있다.
const emoji = "😊";

console.log(Array.from(emoji)); //  ['😊']

String.prototype.normalize()

  • 문자열을 정규화된 양식으로 바꾸어준다.
  • 사실상 동일한 문자가 다른 방식으로 표기됐을 때 이를 올바르게 비교할 수 있게 해준다.
const string1 = "café";
const string2 = "cafe\u0301";

console.log(string1 === string2); // false
console.log(string1.normalize() === string2.normalize()); // true
반응형