給心急的程式設計師的 JavaScript(ES2022 版)
請支持這本書:購買捐款
(廣告,請不要封鎖。)

19 Unicode – 簡要介紹(進階)



Unicode 是用來表示和管理世界上大多數書寫系統中文字的標準。幾乎所有處理文字的現代軟體都支援 Unicode。此標準由 Unicode 聯盟維護。每年都會發布新版本的標準(包含新的表情符號等)。Unicode 1.0.0 版於 1991 年 10 月發布。

19.1 碼點與碼元

了解 Unicode 的兩個概念至關重要

19.1.1 碼點

Unicode 的第一個版本有 16 位元碼點。從那時起,字元的數量大幅增加,碼點的大小已擴充到 21 位元。這 21 位元分為 17 個區,每個區有 16 位元

平面 1-16 稱為補充平面或星體平面

讓我們檢查幾個字元的碼點

> 'A'.codePointAt(0).toString(16)
'41'
> 'ü'.codePointAt(0).toString(16)
'fc'
> 'π'.codePointAt(0).toString(16)
'3c0'
> '🙂'.codePointAt(0).toString(16)
'1f642'

碼點的十六進制數字告訴我們,前三個字元位於平面 0(在 16 位元內),而表情符號位於平面 1。

19.1.2 編碼 Unicode 碼點:UTF-32、UTF-16、UTF-8

編碼碼點的主要方式有三個Unicode 轉換格式 (UTF):UTF-32、UTF-16、UTF-8。每個格式末尾的數字表示其碼單元的位元大小。

19.1.2.1 UTF-32(Unicode 轉換格式 32)

UTF-32 使用 32 位元儲存碼單元,每個碼點一個碼單元。此格式是唯一具有固定長度編碼的格式;所有其他格式都使用不同數量的碼單元來編碼單一碼點。

19.1.2.2 UTF-16(Unicode 轉換格式 16)

UTF-16 使用 16 位元碼單元。它編碼碼點如下

換句話說,最後面的兩個十六進制數字貢獻了 8 位元。但我們只能在 BMP 以以下 2 位元組對之一開頭時使用這 8 位元

每個替代字元,我們有 4 對可供選擇,這就是剩餘 2 位元來自何處。

因此,每個 UTF-16 碼單元永遠都是前導替代字元、後續替代字元,或編碼 BMP 碼點。

以下是兩個 UTF-16 編碼碼點的範例

19.1.2.3 UTF-8(Unicode 轉換格式 8)

UTF-8 具有 8 位元組代碼單位。它使用 1-4 個代碼單位來編碼一個代碼點

代碼點 代碼單位
0000–007F 0bbbbbbb(7 位元組)
0080–07FF 110bbbbb, 10bbbbbb(5+6 位元組)
0800–FFFF 1110bbbb, 10bbbbbb, 10bbbbbb(4+6+6 位元組)
10000–1FFFFF 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb(3+6+6+6 位元組)

註解

三個範例

字元 代碼點 代碼單位
A 0x0041 01000001
π 0x03C0 11001111, 10000000
🙂 0x1F642 11110000, 10011111, 10011001, 10000010

19.2 網頁開發中使用的編碼:UTF-16 和 UTF-8

網頁開發中使用的 Unicode 編碼格式為:UTF-16 和 UTF-8。

19.2.1 原始碼內部:UTF-16

ECMAScript 規範在內部將原始碼表示為 UTF-16。

19.2.2 字串:UTF-16

JavaScript 字串中的字元基於 UTF-16 代碼單位

> const smiley = '🙂';
> smiley.length
2
> smiley === '\uD83D\uDE42' // code units
true

有關 Unicode 和字串的更多資訊,請參閱 §20.7「文字的原子:代碼點、JavaScript 字元、字形群集」

19.2.3 檔案中的原始碼:UTF-8

現今 HTML 和 JavaScript 幾乎總是編碼為 UTF-8。

例如,這是 HTML 檔案通常現在開始的方式

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
···

對於在網頁瀏覽器中載入的 HTML 模組,標準編碼也是 UTF-8。

19.3 字形群集 - 真實的字元

一旦我們考慮到世界上的各種寫作系統,字元的概念就會變得非常複雜。這就是為什麼有幾個不同的 Unicode 術語,它們在某種程度上都表示「字元」:代碼點字形群集字形等。

在 Unicode 中,代碼點是文字的原子部分。

然而,字形群集最接近於顯示在螢幕或紙張上的符號。它被定義為「文字的水平可分段單位」。因此,官方 Unicode 文件也稱它為使用者感知的字元。需要一個或多個代碼點來編碼一個字形群集。

例如,天城文中的 kshi 由 4 個碼點編碼。我們使用 Array.from() 將字串分割成包含碼點的陣列(有關詳細資訊,請參閱 §20.7.1「處理碼點」

Splitting the grapheme cluster for the Devanagari _kshi_ into code points.

旗幟表情符號也是字形群集,由兩個碼點組成,例如日本的國旗

Splitting a flag emoji into code points.

19.3.1 字形群集與字形

符號是抽象概念,也是書面語言的一部分

概念與其呈現方式之間的區別很微妙,在討論 Unicode 時可能會模糊不清。

  有關字形群集的更多資訊

有關更多資訊,請參閱 Manish Goregaokar 的 “Let’s Stop Ascribing Meaning to Code Points”

  測驗

請參閱 測驗應用程式