微網誌

微網誌

簡單

說明

你發現社群媒體市場在極短貼文這塊有個缺口。 既然 Twitter 現在允許 280 個字元的貼文,那些想要快速更新社群動態的人反而沒被服務到。 你決定打造自己的社群媒體網路。

為了讓你的產品與眾不同,你把它做到極端:只允許 5 個字元以內的貼文。 任何超過 5 個字元的貼文都應該截斷成 5 個字元。

為了讓使用者能充分表達自己,你允許 Emoji 和其他 Unicode 字元。

你的任務是把輸入字串截斷成 5 個字元。

文字編碼

以數位形式儲存的文字必須轉換成一連串的位元組。 目前常見的字元對應到位元組的方式有 3 種。

  • ASCII可以編碼英文的字元。 所有字元都恰好佔 1 位元組。
  • UTF-8是一種 Unicode 文字編碼。 字元佔 1 到 4 位元組。
  • UTF-16是一種 Unicode 文字編碼。 字元長度不是 2 位元組就是 4 位元組。

UTF-8 和 UTF-16 都是 Unicode 編碼,這表示它們能夠表示非常多種字元,包括:

  • 世界上大多數語言與文字系統的文字
  • 歷史文本
  • Emoji

UTF-8 和 UTF-16 都是可變長度編碼,這表示不同的字元佔用的空間大小也不同。

來看看字母「a」和 Emoji「😛」。 在 UTF-16 中,字母佔 2 位元組,但這個 Emoji 佔 4 位元組。

這道練習的訣竅,在於使用以 Unicode 字元(碼點)為核心設計的 API,而不是以 Unicode 碼元為核心的 API。

Unicode 編碼點與編碼單元

「一般」的 UTF-16 編碼字串可以表示成一連串字元,其中每個字元最長可達 16 位元(這也是 UTF-16 這個名稱的由來)。這代表以 16 位元(也就是 1 個編碼單元)最多可表示 2¹⁶(2 的十六次方),也就是 65536 種可能的字元。這 65536 個字元構成了所謂的基本多文種平面,它大到足以涵蓋大多數語言中最常見的字元。

不過,有些符號就是無法塞進單一個編碼單元。解決辦法是用兩個編碼單元來表示它們。這兩個 UTF-16 編碼單元(通常也稱為_代理對_)構成一個編碼點。

所以總結來說,講到 UTF-16 編碼時:

  • code unit 是代表單一字元的 16 位元(或更少)。
  • code point 是代表單一字元的一或兩個編碼單元。

更令人困惑的是,還有_字素叢集_,基本上就是應該被視為單一視覺單位的一連串 Unicode 字元(編碼點)。例如某些表情符號,像這個 👨‍👦。

Javascript 中的 UTF-16

大多數 Javascript 內建方法都能處理 UTF-16 編碼的字串,但它們是根據 UTF-16 編碼單元運作的。例如,String.prototype.split("") 方法會依編碼單元來切割字串。

另一方面,String iterators 則是依編碼點來疊代。

你可以在 MDN 上讀到更多內容,並找到關於 Unicode 字串的範例。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟
JavaScript Exercism

準備好開始 微網誌 了嗎?

註冊 Exercism,透過 37 個概念159 個練習 和真人引導來學習並精通 JavaScript,全部免費。