unicode
Unicode 是一種全球通用的字元編碼標準,用於交換並顯示主要的書寫語言。
從 0 開始,每個符號指定一個編碼,稱為碼點(code point),例
U+ 後加接16進制的 Unicode 碼點
U+0000 = null
共有17個平面:1個基本平面 16個輔助平面
依編碼方式可區分為 UTF-8、UTF-16、UTF-32。
UTF-32
每個碼點用4個字節表點。註:字節 == byte
U+0000 = 0x0000 0000
U+597D = 0x0000 597D
UTF-8
UTF-8是一種變長的編碼方法,字符長度從1個字節到4個字節不等。
UTF-16 編碼
依長度分為為基本平面(2 字節)或補助平面(4 字節)。
基本平面: 0x0000-0xFFFF
輔助平面: 0x010000-0x10FFFF
設計上輔助平面被拆成兩個基本平面的字符來表示。
前半段在 0xD800-0xDBFF 後半段在 0xDC00-0xDFFF
轉換公式
基本平面
U+597D = 0x597D
輔助平面
H = Math.floor((c-0x10000) / 0x400)+0xD800
L = (c - 0x10000) % 0x400 + 0xDC00
Javascript 實際上用的是 UCS-2,相等於 UTF-16。
由於JavaScript只能處理UCS-2編碼,造成所有字符在這門語言中都是2個字節,如果是4個字節的字符,會當作兩個雙字節的字符處理。JavaScript的String都受到這一點的影響,無法返回正確結果。
補充:
字符编码笔记:ASCII,Unicode和UTF-8
Unicode与JavaScript详解
字符编码 unicode 及其在javascript 中的使用
unicode 相關方法
unicode 表示法
javascript 可用 \uxxxx 表示單字符,其中 'xxxx' 為碼點。
"\z" === "z" // 跳脫字元
"\172" === "z" // 8進制轉義 、加 1~3位正整數,且整數不大於8
"\x7A" === "z" // \x 加 2 位16進制
"\u007A" === "z" // 、u 加 4 位16進制
超個單一字符需改用雙字節 表示
'\uD83D\uDE80'
es6 可用 \u{xxxx} 表示雙字節
"\u{1F680}" === "\uD83D\uDE80" // true
String.fromCharCode & String.fromCodePoint()
String.fromCharCode方法,用於從碼點返回對應字符,但是這個方法不能識別輔助平面的字符(編號大於0xFFFF)。
String.fromCharCode(0x20BB7);
String.fromCodePoint(42); // "*"
String.fromCodePoint(65, 90); // "AZ"
String.fromCodePoint(0x404); // "\u0404"
String.fromCodePoint(0x2F804); // "\uD87E\uDC04"
String.fromCodePoint(194564); // "\uD87E\uDC04"
String.fromCodePoint(0x1D306, 0x61, 0x1D307) // "\uD834\uDF06a\uD834\uDF07"
charCodeAt() & codePointAt()
charCodeAt,用於回傳 unicode 的值,但是這個方法不能識別輔助平面的字符(編號大於0xFFFF)。
'A'.charCodeAt(0); // 65
'\uD800\uDC00'.codePointAt(0);
此方法可用來測試是基本或是輔助方面
function is32Bit(c) {
return c.codePointAt(0) > 0xFFFF;
}
線上例子
charAt() & at()
charAt方法,返回字符串給定位置的字符,但是這個方法不能識別輔助平面的字符(編號大於0xFFFF)。 但目前無實作…
'abc'.charAt(0) // "a"
normalize()
為了表示語調和重音符號,Unicode提供了兩種方法。一種是直接提供帶重音符號的字符,比如Ǒ(\u01D1)。另一種是提供合成符號(combining character) ,即原字符與重音符號的合成,兩個字符合成一個字符,比如O(\u004F)和ˇ(\u030C)合成Ǒ(\u004F\u030C)。
'\u01D1'.normalize() === '\u004F\u030C'.normalize()