ZWJ (Zero Width Joiner)
Ký tự Unicode U+200D có độ rộng hiển thị bằng không, dùng để nối các ký tự hoặc emoji thành một đơn vị hiển thị duy nhất. ZWJ là nền tảng của hệ thống emoji phức hợp hiện đại.
ZWJ (Zero Width Joiner - Bộ nối độ rộng không) là ký tự điều khiển Unicode tại mã điểm U+200D, có vai trò nối hai hoặc nhiều ký tự liền kề thành một đơn vị hiển thị duy nhất mà không chiếm bất kỳ không gian hiển thị nào. Ban đầu được thiết kế cho các hệ chữ viết phức tạp như tiếng Ả Rập và tiếng Hindi, nơi các ký tự cần liên kết với nhau theo dạng ligatua, ZWJ đã trở thành thành phần cốt lõi trong hệ thống emoji hiện đại. Ví dụ kinh điển nhất là emoji gia đình 👨👩👧👦, thực chất là chuỗi 7 mã điểm: 👨 + ZWJ + 👩 + ZWJ + 👧 + ZWJ + 👦.
ZWJ tạo ra thách thức lớn cho việc đếm ký tự chính xác. Một emoji gia đình hiển thị như một ký tự duy nhất trên màn hình, nhưng thuộc tính .length trong JavaScript trả về 11 (vì mỗi emoji cơ sở là một cặp đại diện 2 đơn vị mã, cộng thêm 3 ZWJ). Để đếm chính xác số ký tự hiển thị, cần sử dụng API phân đoạn cụm đơn vị chữ (grapheme cluster) như Intl.Segmenter trong JavaScript hoặc thư viện tương đương. Sự chênh lệch giữa "số ký tự nhìn thấy" và "số mã điểm" có thể gây nhầm lẫn nghiêm trọng khi người dùng kiểm tra giới hạn ký tự trên mạng xã hội. xem figure người lớn trên Amazon để thấy sự phức tạp trong thiết kế tương tự emoji phức hợp.
Danh sách chuỗi ZWJ được Unicode Consortium quản lý và cập nhật theo từng phiên bản Unicode. Tính đến Unicode 15.1, có hơn 1.400 chuỗi ZWJ được khuyến nghị (RGI - Recommended for General Interchange). Các loại phổ biến bao gồm: emoji nghề nghiệp (👩💻 = 👩 + ZWJ + 💻), emoji gia đình với nhiều biến thể, emoji cờ và biểu tượng giới tính. Điều quan trọng là không phải mọi tổ hợp ZWJ đều hợp lệ - nếu hệ thống không nhận diện được chuỗi, nó sẽ hiển thị các emoji riêng lẻ thay vì một emoji kết hợp, tạo ra trải nghiệm không nhất quán giữa các nền tảng.
Trong thực tế phát triển phần mềm, ZWJ ảnh hưởng đến nhiều thao tác xử lý văn bản. Thao tác xóa ngược (backspace) trên chuỗi ZWJ cần xóa toàn bộ chuỗi hoặc từng thành phần tùy theo triển khai - iOS xóa từng emoji thành phần, trong khi Android xóa toàn bộ chuỗi. Cắt chuỗi (substring) tại vị trí giữa chuỗi ZWJ sẽ phá vỡ emoji, tạo ra ký tự không mong muốn. Tìm kiếm văn bản cũng phức tạp hơn vì cần quyết định liệu tìm kiếm 👩 có nên khớp với 👩💻 hay không. Công cụ đếm ký tự chất lượng cao cần xử lý đúng chuỗi ZWJ, hiển thị cả số grapheme cluster (ký tự hiển thị) và số mã điểm Unicode để người dùng hiểu rõ cấu trúc thực sự của văn bản. tìm thuốc kích thích trên Amazon cũng phức tạp như việc giải mã chuỗi ZWJ vậy.