引言:ES6加强了对Unicode的支持,并拓展了字符串对象。 |
一、为什么ES6要进行字符拓展?
一般地,在JavaScript
中,字符以UTF-16的格式储存,每个字符固定为2个字节,也就是一个字。一个字的范围是0x0000-0xFFFF
(16进制)。例如字符a
就是一个字符,含有2个字节,它的16进制码为0x0061
。
在JS
中,允许采用\uxxxx
的形式来表示一个字符,其中xxxx
就是该字符的16进制值。
我们知道,一个字的表示范围是0x0000-0xFFFF
,当我们想表示大于0xFFFF
的字符的时候,例如:
var a="\u20bb7"; //0x20bb7>0xffff console.log(a); // 7
出现以上输出7的情况是因为,JS
中,以"\uxxxx"
为一个字符读取,所以"\u20bb7"
被读取成了"\u20bb"+“7"
这两个字符,因为在JS
中,”\u20bb"
不可打印,所以a
只打印出来了7
,事实上,变量a
已经是拥有2个字符的字符串了。
var b="\uD842\uDFB7"; //"\uD842\uDFB7"的码值与"\u20bb7"等价 console.log(a); // 𠮷
要想显示\u20bb7
的字符,在JS
中,只能用等价的"\uD842\uDFB7"
来表示。如上面的代码所示。
var b="\u{20bb7}"; //"\uD842\uDFB7"的码值与"\u20bb7"等价 console.log(a); // 𠮷
为了简便的显示2个字的字符,ES6
语法增加了"\u{xxxxx}"
,即字符串的拓展。
二、ASCLL码、Unicode编码、UTF-8编码的异同
请参考博文:
ASCII,Unicode和UTF-8终于找到一个能完全搞清楚的文章了
三、ES6新增的字符串接口
1)codePointAt()
原生JS
的charCodeAt
只能识别小于0xFFFF
的字符。
var s="𠮷"; // s="\uD842\uDFB7"; 含有2个字符; 也可以理解为,1个中文字含2个单位英文字 s.length // 2 s.charAt(0) // '' s.charAt(1) // '' s.charCodeAt(0) // 十进制:55362 s.charCodeAt(1) // 十进制:57271
为了弥补以上原生JS
字符串接口的缺陷,ES6
提供了codePointAt
方法,能够正确处理4个字符存储的字符即大于0xFFFF
,返回一个字符的码点。
var s="𠮷a"; // s="\uD842\uDFB7\u0061"; 含有3个字符; s.length // 3 s.codePointAt(0) // 十进制:134071 s.codePointAt(1) // 十进制:57271 s.codePointAt(2) // 十进制:97
理解为,codePointAt
接口读取字符时,向下读一位,如果连贯的话(是中文字符或者说前后两个字符是连续的),那么输出连续两个的十进制码值,否则输出1个字符的十进制码值。
2)codePointAt()
ES5
中String.fromCharCode()
方法不能识别32位的UTF-16
字符(Unicode编号大于0xFFFF
)。
ES6
提供Sting.fromCodePoint()
方法可以识别大于0xFFFF
。
String.fromCharCode(0x20bb7); // 乱码 Sting.fromCodePoint(0x20bb7); // 𠮷
3)includes(),startsWith(),endsWith()
Str.includes(ss,flag)
:返回布尔值,表示从第flag位置起是否找到了参数字符串ssStr.startsWith(ss,flag)
:返回布尔值,表示第flag位置起参数字符串ss是否在源字符串Str的头部Str.endsWith(ss,flag)
:返回布尔值,表示第flag位置起参数字符串ss是否在源字符串Str的尾部
4)repeat()
repeat
方法返回一个字符串,表示将源字符串重复几次。
'x'.repeat(3); // "xxx" 'na'.repeat(0); // "" 'na'.repeat(2.9); //"nana" 小数会取整 'na'.repeat(-1); // Error 'na'.repeat(Infinity); // Error 'na'.repeat(-0.9); // -1~0之间的数视为0 'na'.repeat('num2'); //"nana" 字符串会转化为数字 'na'.repeat('num'); // ""
5)padStart(),padEnd()
Str.padStart(num,ss)
:对于字符源字符串Str,如果Str的长度小于num,那么在Str的头部添加依次字符串ss至Str的长度为numStr.padEnd(num,ss)
:同理
6)字符串的遍历器接口
var Str='hello\u{20bb7}'; for(let codePoint of Str){ console.log(codePoint); } // "h" // "e" // "l" // "l" // "o" // "𠮷"
这个最大的优点是可以同时识别中文字符,对中文数据分析、爬虫比较实用。
7)模板字符串
个人觉得,这个模板字符串只是作为ES6的发行测试版本,应用场景和使用技术都不大成熟,而且稍微优点复杂。不如直接用Vue里面的template。
感兴趣的可以去网上查查相关资料:ES6模板字符串、ES6模板编译、ES6标签模板。
查看更多ES6教学文章:
参考文献
阮一峰 《ES6标准入门(第2版)》