[...'👨👨👦👦'] => ["👨", "", "👨", "", "👦", "", "👦"]
b
,計算機最小的存儲單位,以 0/1 來表示值B
,8 個比特表示一個字節在計算機內部,全部的信息最終都表示爲一個二進制的序列。每個二進制位 ( Bit ) 有 0 和 1 兩種狀態,所以八個二進制位就能夠組合出 256 種狀態,這被稱爲一個字節 ( Byte ) ,也就是說,一個字節一共能夠用來表示 256 種不一樣的狀態或者符號。若是咱們製做一張對應表格,對於每個 8 位二進制序列,都對應惟一的一個符號。每個狀態對應一個符號,就是 256 個符號,從 0000 0000 到 1111 1111 。html
ASCII (American Standard Code for Information Interchange,美國信息交換標準代碼)git
1967 年發佈,最後更新於 1986 年,共定義了 128 ( 2⁷ ) 個字符( 0x00 - 0x7F ) ,其中 33 個字符爲不可打印字符 ( 0x00 - 0x1F & 0x7F ),95 個可打印字符 ( 0x20 - 0x7E )正則表達式
可打印字符爲標準鍵盤中可輸入的字符,以下所示:算法
10 個數字 (0-9
),26×2 個大小寫字母 (a-z A-Z
) ,32 個標點符號 1 個空格 (,./;'[]\-=~!@#$%^&*()_+{}|:"<>?
)
ASCII 的侷限在於只能顯示 26 個基本拉丁字母、阿拉伯數目字和英式標點符號,所以只能用於顯示現代美國英語,而其餘攜帶相似於重音符號的字母沒法顯示 ( naïve、café )數據庫
因爲 ASCII 的自然不足,它的變種體迅速出現,兼容字符集對ASCII的處理segmentfault
該標準來自數個國家標準,最主要的是美國的 ASCII 標準,ISO 646 爲了表示歐洲各類語言的帶附加符號( diacritical mark )的變音字母,因爲沒有碼位空間去直接編碼這些變音字母,因此用幾個標點符號來兼做變音字母的附加符號瀏覽器
擴展字符:0xA0 ( 160 ) - 0xFF ( 255 )
淘汰了 ISO 646 編碼標準 服務器
ISO 8859 統一了此前各國各語言的單獨編碼的混亂局面;廢棄了 ISO 646 使用的退格鍵開始的轉義序列來表示變音字母的方法,而是在 G1 區域直接編碼表示變音字母。工具
ISO 8859 有 15 個子版本( 1-11,13-16 ),其中囊括了大部分歐州語言,英語由於沒有重音字母,全部可使用其中任何一個子版本表示優化
Microsoft Codepage 1252 爲 ISO 8859-1 的超集,擴充了 0x80 - 0x9F 來編碼一些可打印字符 ( € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ž ‘ ’ 「 」 • – — ˜ ™ š › œ ž Ÿ )
例如在中國 GB/T 1988-80 標準中: $
u+0024 替換爲 ¥
u+00A5 ,~
u+007E 替換爲 ‾
u+203E
Windows 操做系統上的 ANSI 編碼並非指的是美國國家標準學會 ( ANSI ),而是用來指稱多個不一樣的代碼頁,好比在簡體中文編碼操做系統中,ANSI 實際使用 GB 系字符編碼
現行版本
Unicode ( 萬國碼、國際碼、統一碼、單一碼 )
最第一版本:1.0.0 發佈,1991 年 10 月發佈,7161 個字符
當前正式版本 Unicode 11.0 ( 2018 年 6 月 ) 擁有 137374 個字符
當前最新版本:Emoji 12.0 Beta
表示方法:
該字符集包括了其餘全部字符集,保證了與其餘字符集的雙向兼容,ISO 10646 有三種實現級別,不一樣的實現級別能支持的字符數量不一樣
與 Unicode 的關係:
Unicode 是一個字符集,其實現方式稱爲 Unicode 轉換格式,即 UTF
Unicode 與 UCS 合併以前已經產生了 UCS-4 編碼方式,UCS-4 使用了 32 位來表示每一個編碼,爲了兼容 Unicode 產生了 UTF-32 標準,編碼空間限制在了 0x000000 - 0x10FFFF 之間,所以能夠說 UTF-32 是 UCS-4 的子集。因爲 UTF-32 的編碼空間佔用過大,所以在 HTML5 標準中明確規定不能使用 UTF-32 進行編碼
UTF-16 編碼擁有定長和變長兩個編碼特色,對於 Unicode 基本平面的字符,UTF-16 佔用兩個字節,對於輔助平面的字符,UTF-16 編碼佔用四個字節
Unicode 規範定義,每個文件的最前面分別加入一個表示編碼順序的字符,這個字符的名字叫作 「零寬度非換行空格 ( zero width no-break space )」,用 FE FF 表示。但在不一樣計算機系統中對字節順序的理解是不一致的,即出現了大端序 ( UTF-16 BE ) 與小端序 ( UTF-16 LE ) 兩種狀況。文本頭部使用 FE FF 與 FF FE 進行區分,此區分符稱爲「字節順序標記 ( BOM ) 」
如何肯定雙字節和四字節:
在基本平面內,從 U+D800 到 U+DFFF 是一個空段,不對應任何碼點,這個空段用來映射輔助平面的字符,即一個輔助平面的字符,被拆成兩個基本平面的字符表示。
例如: 👨 能夠表示爲 U+D83D U+DC68
因爲前兩種編碼方式的編碼規則對與英語國家來講很是浪費(2-4 字節編碼)
UTF-8 當前使用 1-6 個字節爲每一個字符編碼
JavaScript 採用了 Unicode 字符集。可是隻支持一種編碼方式。JS 最早採用的編碼既不是 UTF-16 也不是 UTF-32 或 UTF-8 ,而是 UCS-2 。UTF-16 明確宣佈是 UCS-2 的超集。UTF-16 中基本平面字符延用 UCS-2 編碼。輔助平面字符定義了 4 個字節的表示方法。
JS 只能處理 UCS-2 編碼,形成全部字符在這門語言中都是兩個字節,若是是四個字節的字符。會被當作兩個雙字節的字符處理。
二者的關係簡單說,就是 UTF-16 取代了 UCS-2,或者說 UCS-2 整合進了 UTF-16。因此,如今只有 UTF-16,沒有 UCS-2。
字符會從 0 開始爲每一個字符指定一個編碼, 這個編碼叫作碼點
舉例
Unicode 中給字符進行分區定義,每一個區稱爲一個面,Unicode 擁有 0-16 共 17 個平面,每一個平面 16⁴ 個字符
平面 | 字符值 | 描述 |
---|---|---|
0號平面 | U+0000 - U+FFFF | 基本多文種平面 |
1號平面 | U+10000 - U+1FFFF | 多文種補充平面 |
2號平面 | U+20000 - U+2FFFF | 表意文字補充平面 |
3號平面 | U+30000 - U+3FFFF | 表意文字第三平面(未正式使用) |
4 - 13號平面 | U+40000 - U+DFFFF | (還沒有使用) |
14號平面 | U+E0000 - U+EFFFF | 特別用途補充平面 |
15號平面 | U+F0000 - U+FFFFF | 保留做爲私人使用區(A區) |
16號平面 | U+100000 - U+10FFFF | 保留做爲私人使用區(B區) |
爲何 Windows 上使用 Notepad 會出現亂碼
Windows 上的 Notepad 軟件在保存文件時默認使用的是 ANSI 編碼保存,而在打開的時候須要猜想 txt 文件的編碼方式,若是文檔中出現了 ANSI 編碼之外的字符,則在打開時候可能會出現編碼識別錯誤的狀況,因爲 txt 文件爲純文本文件,沒有保存文檔編碼信息的區域,則此問題可能一直存在。
解決該問題可在保存文件的時候使用 UTF-8 編碼保存,但須要注意的是:
Windows 的 Notepad 應用使用 UTF-8 保存的時候實際使用的爲 UTF-8 BOM 方式,其表現爲在文本最開頭添加 EF BB BF ,這部分稱爲
UTF-8 字節順序標記
,該方式並不是強制標準,若是在代碼文件中使用該方式保存則有可能出現運行錯誤。
當前 iOS 12 使用的 Unicode 版本爲 11,而大衆使用比較的 Android 8.0 使用的Unicode 版本爲 9,若是在 Android 系統中出現了新版本的字符,則會出現沒法顯示或顯示錯誤的狀況。
例如在 Unicode 8.0 中加入了 5 個菲茨帕特里克修飾符,用來調節人形表情的膚色,若是在低於此版本的 Unicode 中顯示的字符爲兩個字符,分別是顏色加人偶。
另外 Unicode 新版本中使用 U+200D 零寬連字 ( ZWJ ) 將多個 Emoji 連起來,例如 👨👨👦👦 => 👨👨👦👦
Emoji 表情佔用 4 個字節,可是 MySQL 數據庫使用的 utf-8 默認編碼最多隻能存儲 3 個字節 ( UTF-8 標準支持最長編碼爲 6 字節 ),就會致使存儲不進去,在讀取的時候讀取不完整,致使亂碼
修復方法爲:修改數據庫字符集爲 uft8mb4,若是數據庫鏈接池中對字符集做出了設置須要在連接中去掉 characterEncoding 參數
Windows 系列系統使用的換行標誌爲 CRLF,該換行標誌與 Unix/Linux 的 LF 換行及 macOS 的 CR 換行不相同。
若是在代碼工程中使用了 Code Lint 工具自動格式化,可能會使代碼中的 LF 換行自動轉換爲 CRLF 換行,Git 中也能捕獲或忽略這個變化。
另外,從 Windows 10 1803 開始,支持 Unix/Linux 的 LF 換行及 macOS 的 CR 換行。
[...'👨👨👦👦'] => ["👨", "", "👨", "", "👦", "", "👦"]
👨👨👦👦 是 2015 年添加到 Emoji 2.0 中的新字符,使用 U+200D 零寬連字 (ZWJ) 將4個 Emoji 連起來,可以使用如下代碼檢測
[...'👨👨👦👦'].forEach(e=>{console.log(e.codePointAt().toString(16))})
新版本 ECMAScript 針對 JavaScript 編碼問題作了哪些改進
因爲 JavaScript 使用的是隻支持雙字節編碼的 USC-2 編碼方式,因此全部超過二字節編碼的 Unicode 字符都沒法在 JavaScript 中處理
例如 '👨'.charCodeAt().toString(16)
輸出的結果爲 d83d
,而👨的Unicode 碼點卻不是 d83d
,形成這樣的緣由爲 JavaScript 只處理了該字符的前兩個字節
爲了解決這些問題,ECMAScript 6 種加強了對新版本 Unicode 的支持。
例如:
'\ud83d\udc68' === '👨' === '\u{1F468}'
String.fromCodePoint()
和 String.prototype.codePointAt()
等方法代替 String.fromCharCode()
和String.prototype.charCodeAt()
等方法,以用於支持 UTF-16 編碼字符'\u01D1'.normalize() === '\u004F\u030C'.normalize()
爲何使用 Google Chrome 打開 JS 文件,文件中的中文字符會變成亂碼
因爲 2017 年更新的某版本 Chrome 中,去除了對 JS 文件默認編碼 UTF-8 的支持,使用了系統默認編碼(例如中文操做系統使用 GB18030 )對 JS 文件的解碼,因此致使 JS 文件中的中文字符變成亂碼。
解決方法有兩種:
第二次在 segmentfault 上發文章,歡迎各位評論區中吐槽指正