这篇文章介绍 ES6 中针对 unicode 字符串的几个新增函数。
-
String.prototype.codePointAt
函数类型:(index?: number)=> number|undefined
codePointAt
是一个原型函数,它依据传入的index
参数,返回字符串中位于该处的字符的 码点 (code point)值。这个办法能够辨认utf-16 中的 4 字节 码点,反对的范畴比原型函数charCodeAt
更广,charCodeAt
只能辨认 2 字节 的根本立体字符 (BMP)。另外,当index
越界时,codePointAt
返回undefined
,charCodeAt
返回NaN
。除了这两点之外,
codePointAt
和charCodeAt
的后果基本一致:index
的参数默认值都为0
-
当字符处于根本立体字符集的时候,二者返回的后果是一样的。
const str = 'abc'; // 字符 'a' 位于根本立体字符集中 console.log(str.codePointAt(0));//97 //index 默认值为 0 console.log(str.codePointAt());//97 //index 越界时,返回 undefined console.log(str.codePointAt(5));//undefined console.log(str.charCodeAt(0));//97 //index 默认值为 0 console.log(str.charCodeAt());//97 //index 越界时,返回 NaN console.log(str.charCodeAt(5));//NaN
-
当字符处于辅助立体字符集的时候,
codePointAt
可能正确辨认,并返回对应字符的码点(code point)。charCodeAt
不能正确辨认,只能返回以后地位的 2 字节字符的码点。比方,对于辅助立体的低音字符 𝄞,它由 两个 2 字节 的根本立体字符
0xd834
和0xdd1e
示意。当咱们对𝄞应用
charCodeAt
时,只能失去对应地位的码点。const str = '\ud834\udd1e'; // 辅助立体字符 低音字符 𝄞 console.log(str.charCodeAt(0).toString(16)); //d834 console.log(str.charCodeAt(1).toString(16)); //dd1e
当咱们应用
codePointAt
时,能够失去 𝄞 的码点0x1d11e
。console.log(str.codePointAt(0).toString(16)); //1d11e // 当 index 为 1 时,'\udd1e' 前面没有另一个代码单元,被认为只是一个 2 字节的字符,而非是一对代码单元,所以此时只返回 '\udd1e' 的码点,而非 '\ud834\udd1e' 的码点 console.log(str.codePointAt(1).toString(16)); //dd1e
-
String.fromCodePoint
函数类型:
(...codePoints: number[])=> string
动态函数
fromCodePoint
是依据传入的 unicode 码点返回对应的字符串,和fromCharCode
相比,它反对间接传入辅助立体的码点值了。还是以低音符号 𝄞 为例,应用fromCodePoint
能够间接传入码点值0x1d11e
,而fromCharCode
值须要传入0xd834
和0xdd1e
。console.log(String.fromCodePoint(0x1d11e)); //𝄞 console.log(String.fromCodePoint(0xd834, 0xdd1e)); //𝄞 console.log(String.fromCharCode(0x1d11e)); //턞 不能正确辨认,乱码 console.log(String.fromCharCode(0xd834, 0xdd1e)); //𝄞
对于根本立体的字符,
fromCodePoint
和fromCharCode
后果是一样的。console.log(String.fromCodePoint(97)); //'a' console.log(String.fromCodePoint(97, 98)); //'ab' console.log(String.fromCodePoint()); //''console.log(String.fromCharCode(97)); //'a'console.log(String.fromCharCode(97, 98)); //'ab'console.log(String.fromCharCode()); //''
-
String.prototype.normalize
函数类型:
(form:'NFC'|'NFD'|'NFKC'|'NFKD')=>string
原型函数
normalize
承受一个指定正规化(如果你不明确 NFC、NFD 等的意义,点一下)模式的参数form
,form
默认值为 ’NFC’(Normalization Form Canonical Composition,以规范等价形式来合成,而后以规范等价重组),返回正规化的字符串。unicode对 合成符号 (字符中的字母带有腔调等附加符号)提供了 两种 示意形式,一种是应用 一个 unicode 码点 示意,一种是将合成字符中的字母与附加符号组合,应用两个码点 ,比方
ń
是一个合成符号,咱们既能够应用一个码点0x0144
示意,也能够应用两个码点0x006e
和0x0301
示意。const str1 = '\u0144'; //ń const str2 = '\u006e\u0301'; //ń console.log({ str1, str2, });//{str1: 'ń', str2: 'ń'}
这两种示意形式,是视觉和语义上都是雷同的,它们是规范等价的。然而,在代码层面它们却是不同的,
str1
是 一个码点 ,str2
是两个码点,这很有可能会导致问题。console.log(str1.length, str2.length);//1 2 console.log(str1 === str2);//false
normalize
函数便是为了解决这种问题,两个字符串通过normalize
函数实现正规化之后,就不会再呈现这种问题了。let str1 = '\u0144'; //ń let str2 = '\u006e\u0301'; //ń // 正规化 str1 = str1.normalize(); str2 = str2.normalize(); console.log({ str1, str2, }); //{str1: 'ń', str2: 'ń'} console.log(str1.length, str2.length); //1 1 console.log(str1 === str2); //true
-
新增的 unicode 示意办法
在之前,咱们示意 unicode 字符能够通过
\u+ 码点
的形式,ES6 新增了一种示意形式,即\u+{码点}
。这两种形式的不同之处,也很容易想到,
\u+{码点}
反对写入辅助立体的 4 字节码点,而\u+ 码点
仅反对根本立体的 2 字节码点。// 对于根本立体的 2 字节码点,两种没有区别 const str1 = '\u{0144}'; const str2 = '\u0144'; console.log(str1 === str2); //true // 低音符号 const str3 = '\u{1d11e}'; // 谬误的示意办法,被辨认为了 \u1d11 和 e 两个字符 const str4 = '\u1d11e'; console.log(str4,str3===str4); //ᴑe false
unicode 的确让人头痛,如果有敌人对于 unicode 不太理解,能够在评论区留言,我会再发一篇具体介绍 unicode 与 JS 的文章。