簡單來談談Unicode與emoji

gdutwyg發表於2019-03-04

什麼是Unicode

Unicode是國際組織制定的可以容納世界上 所有文字和符號的字元編碼方案,它為每種語言中的每個字元設定了統一併且唯一的編碼。

表示一個Unicode的字元時,通常會用“U+”然後緊接著一組十六進位制的數字來表示這一個字元。比如: U+4E25,U+1F600, U+1F601

那unicode和UTF-8有何區別?

通俗點就是

  • Unicode 是「字符集」
  • UTF-8 是「編碼規則」

字符集:為每一個「字元」分配一個唯一的 ID(學名為碼位 / 碼點 / Code Point)
編碼規則:將「碼點」轉換為位元組序列的規則

JS中如何使用Unicode

編碼

1.字串形式
javaScript 允許採用 uxxxx形式表示一個字元,其中xxxx表示字元的 Unicode 碼點。僅限於碼點在 u0000~uFFFF之間的字元。超出這個範圍的字元,必須用兩個雙位元組的形式表示。

"u0061" // `a`

// es6表示法(支援超過0xFFFF的數值)
"u{1F601}"
複製程式碼
  1. js方法

es5: String.fromCharCode(Unicode) (侷限於Unicode 碼點不大於0xFFFF)

String.fromCharCode(65) //return "A"
複製程式碼

es6: String.fromCodePoint(Unicode) (支援Unicode 碼點大於0xFFFF)

String.fromCodePoint(`0x1F601`) // "?"
String.fromCodePoint(`128513`) // "?"
複製程式碼

解碼

es5: str.charCodeAt() (侷限於Unicode 碼點不大於0xFFFF)

var str = `ABC`
str.charCodeAt(0) // 65
複製程式碼

es6: str.codePointAt() (支援Unicode 碼點大於0xFFFF)

var str = "?"
str.codePointAt(0) // 128513 10進位制
str.codePointAt(0).toString(16) // "1f601" 16進位制
複製程式碼

emoji的編碼

emoji 也是一個Unicode字元。2010年,Unicode 開始為 Emoji 分配碼點。
比如:U+1F4C5,U+1F468, U+1F600
Unicode 只是規定了 Emoji 的碼點和含義,並沒有規定它的樣式。舉例來說,碼點U+1F600表示一張微笑的臉,但是這張臉長什麼樣,則由各個系統自己實現。

如果使用者的系統沒有實現這個Emoji符號,使用者就會看到一個沒有內容的方框,因為系統無法渲染這個碼點。

截至目前,共有2789個emoji字元;
參考連結:emoji-text

emoji組合

Unicode 允許多個碼點組合表示一個 Emoji。
通過 零寬度連線符U+200D實現。

U+1F468:男人
U+1F469:女人
U+1F467:女孩
比如U+1F468 U+200D U+1F469 U+200D U+1F467,就會顯示為一個 Emoji ?‍?‍?
如果使用者的系統不支援這種方法,就還是顯示為三個獨立的 Emoji ???
複製程式碼

零寬連字元(zero-width-joiner,ZWJ)是一個不列印字元,放在某些需要複雜排版語言(如阿拉伯語、印地語)的兩個字元之間。
零寬連字元使得這兩個本不會發生連字的字元產生了連字效果。零寬連字元的Unicode碼位是U+200D

// 多碼點轉成emoji組合
function unifiedToNative(unified) {
  var unicodes = unified.split(`-`),
      codePoints = unicodes.map((u) => `0x${u}`)

  return String.fromCodePoint(...codePoints)
}

// 多組合emoji 轉成碼點
var s = `?‍❤️‍?`;
for (let ch of s) {
  console.log(ch.codePointAt(0).toString(16)); // 1f469 200d 2764 fe0f 200d 1f469
}
複製程式碼

感謝閱讀。

這是個人隨筆的地址,如果喜歡,star一個唄 ^_^

參考資料:

相關文章