
문자열을 입력받아 어떤 처리를 하는 알고리즘 문제를 풀다가 생각지 못한 이슈가 있었다.
예를 들어서 'Hello'라는 문자열이 입력됐을 때 단순히 split('')으로 각 문자를 접근해서 문제를 해결했었는데 이모티콘에서는 예상했던 것과 다르게 동작하는 문제점이 있었다.
이모티콘에서 split, spread를 사용했을 때 다른 동작이 일어난다.
🐝 (벌): U+1F41D
- High Surrogate: 0xD83D (U+D83D)
- Low Surrogate: 0xDC1D (U+DC1D)
💕 (두 개의 하트): U+1F496
- High Surrogate: 0xD83D (U+D83D)
- Low Surrogate: 0xDC96 (U+DC96)
🐙 (문어): U+1F419
- High Surrogate: 0xD83D (U+D83D)
- Low Surrogate: 0xDC19 (U+DC19)
split('') 메서드는 문자열을 빈 문자열을 기준으로 나누어 각 문자(또는 코드 유닛)를 배열의 요소로 반환한다.예)
const emojiString = '🐝💕🐙';
const result = emojiString.split('');
console.log(result);
결과)
// ['\uD83D', '\uDC1D', '\uD83D', '\uDC95', '\uD83D', '\uDC19']
예)
const emojiString = '🐝💕🐙';
const result = [...emojiString];
console.log(result);
결과)
// ['🐝', '💕', '🐙']
split('')는 이모티콘을 구성하는 각 코드 유닛으로 나누어 반환하는 반면,
스프레드 연산자는 이모티콘을 전체로 처리하여 배열의 각 요소로 반환한다.
이 두 방법은 이모티콘을 처리하는 방식이 다르므로, 결과도 다르게 나타난다.
Surrogate Pair는 UTF-16 인코딩에서 사용되는 개념으로, 16비트(2바이트)로 표현할 수 없는 유니코드 문자를 표현하기 위해 두 개의 16비트 코드 유닛을 사용하는 방법이다.
이는 주로 유니코드의 코드 포인트가 0x10000(65536) 이상의 문자에 해당할 때 사용된다.
UTF-16에 대한 설명을 아래에서 더 자세히 다루겠다.
Surrogate Pair는 두 개의 16비트 코드 유닛으로 구성된다:
1. High Surrogate: 0xD800에서 0xDBFF 사이의 값으로, 상위 16비트이다.
2. Low Surrogate: 0xDC00에서 0xDFFF 사이의 값으로, 하위 16비트입이다.
이 두 개의 코드 유닛을 결합하여 하나의 유니코드 코드 포인트를 표현한다.
예를 들어, 코드 포인트 U+10000은 다음과 같이 표현됩니다:
High Surrogate: 0xD800
Low Surrogate: 0xDC00
U+10000 (65536) → Surrogate Pair: 0xD800 0xDC00
U+1F600 (😀) → Surrogate Pair: 0xD83D 0xDE00
Surrogate Pair는 주로 다음과 같은 경우에 사용된다:
Surrogate Pair는 UTF-16 인코딩을 사용하는 시스템에서만 적용된다.
따라서 모든 프로그래밍 언어나 시스템에서 공통적으로 적용되는 개념은 아니다.
예를 들어:
UTF-8은 가변 길이 인코딩 방식으로, Surrogate Pair 개념이 필요하지 않다.
UTF-8에서는 1바이트에서 4바이트까지 사용하여 모든 유니코드 문자를 표현할 수 있습니다.
UTF-32는 고정 길이 인코딩 방식으로, 모든 유니코드 문자를 4바이트로 표현하므로 Surrogate Pair가 필요하지 않다.
JavaScript는 내부적으로 문자열을 UTF-16 인코딩 방식으로 처리한다.
이는 JavaScript의 문자열이 16비트 코드 유닛으로 구성된다는 것을 의미합니다.
JavaScript의 문자열은 기본적으로 16비트(2바이트) 단위로 구성된다.
이는 ASCII 문자와 같은 기본 문자들은 1개의 16비트 코드 유닛으로 표현되지만, 유니코드의 더 높은 코드 포인트(예: 이모티콘, 특정 언어의 문자 등)는 Surrogate Pair를 사용하여 두 개의 16비트 코드 유닛으로 표현됩니다.
UTF-16에서 0x10000 이상의 코드 포인트는 두 개의 16비트 코드 유닛으로 나누어 표현된다.
예를 들어, 이모티콘 '🐝' (U+1F41D)는 다음과 같이 표현:
High Surrogate: 0xD83D
Low Surrogate: 0xDC1D
JavaScript에서 문자열을 다룰 때, 문자열의 길이는 16비트 코드 유닛의 수로 계산된다.
따라서 Surrogate Pair를 사용하는 문자는 문자열의 길이를 계산할 때 두 개의 코드 유닛으로 간주된다.
예)
const emoji = '🐝';
console.log(emoji.length); // 2 (Surrogate Pair로 인해 두 개의 코드 유닛으로 계산됨)
const str = 'Hello, World!';
console.log(str.length); // 13 (각 문자가 1개의 16비트 코드 유닛으로 표현됨)
JavaScript는 UTF-16 인코딩을 사용하여 문자열을 처리하며, 이는 문자열의 각 문자가 16비트 코드 유닛으로 표현된다는 것을 의미한다.
이로 인해 Surrogate Pair를 사용하는 문자는 문자열의 길이를 계산할 때 두 개의 코드 유닛으로 간주된다.