항상 ASCII에 있는 문자만 사용했기 때문에 이모지가 어떻게 메모리에 공간을 차지하는지에 대해서는 생각을 해보지 못했습니다. 오늘 코드를 짜다가 이모지가 같은 공간을 차지하고 있다고 착각하여 결과가 많이 다르게 나왔고, 해당 부분을 고려하지 못해서 오류 원인을 찾느라 정말 많은 시간을 투자했습니다. 이모지가 여러 바이트를 차지할 수 있음을 알고 다음에는 주의하도록 하겠습니다! 😊

const bookings = room.isBooked.map(slot => slot ? "🁢🁢" : "xx").join("|");
const morningBookings = bookings.slice(0, 3); // 오전 시간
const afternoonBookings = bookings.slice(4); // 오후 시간
• bookings 문자열을 분할할 때, 인덱스 범위가 잘못되었음. 이모지는 여러 바이트를 차지할 수 있어, 문자열을 직접 분할할 때 예상치 못한 결과가 나올 수 있다.
• bookings 문자열을 3과 4의 인덱스에서 자르면서 중간에 이모지가 잘려 출력이 깨졌다.
const bookings = room.isBooked.map(slot => slot ? "🁢🁢" : " ");
const morningBookings = bookings.slice(0, 4).join("|"); // 오전 시간
const afternoonBookings = bookings.slice(4).join("|"); // 오후 시간
• room.isBooked 배열의 각 요소를 이모지 또는 공백 문자열로 변환한 후 join 메서드로 결합하여 오전과 오후 시간대로 나눴다.
• bookings 배열을 두 번에 걸쳐 slice와 join을 사용하여 오전 시간대(0-3)와 오후 시간대(4-7)로 나누었다. 이렇게 하면 문자열이 잘리지 않고 제대로 출력된다.
기존 코드에서는 문자열을 잘못 분할하여 이모지가 깨지는 문제가 발생했다. 이를 해결하기 위해 map과 join 메서드를 사용하여 문자열을 올바르게 결합하고, 인덱스 범위를 정확하게 지정하여 slice 메서드로 분할함으로써 문제를 해결했다.
먼저 프로그래밍 언어에서는 UTF-8 인코딩을 사용하기 때문에 해당 개념을 먼저 알아보자 UTF-8은 가변 길이의 문자 인코딩 방식으로, 1바이트에서 4바이트까지의 길이를 가질 수 있다.
• ASCII 문자 (U+0000 to U+007F): 1바이트
• 라틴어 보충 (U+0080 to U+07FF): 2바이트
• 기본 다국어 평면 (U+0800 to U+FFFF): 3바이트
• 보충 평면 (U+10000 to U+10FFFF): 4바이트
이모지는 주로 보충 평면에 속하며, UTF-8 인코딩에서는 4바이트를 차지한다. 예를 들어, ‘🁢’ 이모지는 UTF-8 인코딩에서 4바이트를 사용한다.
function getUTF8Bytes(string) {
return new TextEncoder().encode(string);
}
const emoji = "🁢";
const bytes = getUTF8Bytes(emoji);
console.log(`The emoji ${emoji} is represented by ${bytes.length} bytes in UTF-8.`);
console.log(bytes); // 출력된 바이트 배열
해당 코드를 실행시켜 보면 결과는 다음과 같다.
The emoji 🁢 is represented by 4 bytes in UTF-8.
Uint8Array(4) [ 240, 159, 129, 162 ]
• 이모지는 UTF-8 인코딩에서 일반적으로 4바이트를 차지한다.
• 이모지가 여러 바이트를 차지하기 때문에 문자열을 인덱싱할 때 예상치 못한 결과가 발생할 수 있다.
• 이를 해결하기 위해 map과 join 메서드를 사용하여 문자열을 올바르게 조작하는 것이 중요하다.