[...'👨👨👦👦'] => ["👨", "", "👨", "", "👦", "", "👦"]
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 上发文章,欢迎各位评论区中吐槽指正