ES6的Unicode

在ES6之前,JS字符串是基于16位的字符编码进行构建。每16位的序列是一个编码单元,代表一个字符。但是现在这16位满足不了字符数量的需求了。

UTF-16码位

  • Unicode目的是给每一个字符提供唯一的数字标识,也称为码位(code point),从0开始。
  • 用来表示字符的数字标识(码位),称为字符编码(character encode)。

现在字符有两种表示,完全依照UTF-16的表示方式:

  • 16位的字符,基本多文种平面(BMP),即只有一个编码单元
  • 32位的字符,也叫代理对,包含两个编码单元

ES5所有的字符串操作基于16位的字符(即使此字符使用32位表示的)。
ES5代码,IE11控制台的运行结果:

var e = '😅';
=> undefined
e.length
=> 2
/^.$/.test(e)
=> false
e.charAt(0)
=> "���"
e.charAt(1)
=> "���"
e.char
=> undefined
e.charCodeAt(0)
=> 55357
e.charCodeAt(1)
=> 56837

长度属性是2,而且第一个和第二个编码单元不是一个BMP,显示乱码。

codePointAt方法

ES6新增方法。完全支持UTF-16。

var e = '😅a';
=> undefined
e.length
=> 2
e.codePointAt(0)
=> 128517
e.codePointAt(1)
=> 56837
e.codePointAt(2)
=> 97

e.charCodeAt(0)
=> 55357
e.charCodeAt(1)
=> 56837
e.charCodeAt(2)
=> 97

到了ES6,长度属性依然是2。
但是,e.codePointAt(0)返回的是一个完整的UTF-16编码,而非半个16位编码,是大于0xFFFF的。因此,可以借此判断字符占用的编码单元数量。