字符的Unicode表示法
javaScript允许使用\uxxxx来表示一个字符,且这个字符在\u0000-\uFFFF之间
例如,\u0061可以表示字符’a’
但是’\u20BB7’,js就不能再正确识别,他会显示一个空格,后跟一个数字7。
ES6对此作了改进,只要将码点,也就是\uxxxx里面的x,放入大括号内,就可以正确解读,
'\u{20BB7}'
// '吉'
codepointAt()
Js内部固定以UTF-16格式存储,每个字符固定为2个字节,对于需要一个字符需要4个字节编码的字符,也就是unicode码点大于0xFFFF的字符,Js会认为他们是两个字符。
var s = '吉'
s.length//2
s.charAt(0)//''
s.charAt(1)//''
s.charCodeAt(0)//55362
s.charCodeAt(1)//57271
吉的码点是0x20BB7,UTF-16编码为0xD842 0xDFB7,需要4个字节存储,对于这种4个字节的字符,charAt无法识别,charCodeAt只能分别返回前2个字节和后2个字节的值,但是codePointAt确可以
var s = '吉a'
s.codePointAt(0)//134071
s.codePointAt(1)//57271
s.codePointAt(2)//97
s.codePointAt()能够识别一个4个字节的字符,这里的s.codePointAt(0)就是‘吉’这个字符对应的十进制码点,s.codePointAt(1)就是吉这个字符的后两个字节,注意的是,
codePointAt返回的是码点的十进制,如果想返回十六进制,可以使用toString方法
var s = '吉a'
s.codePointAt(0).toString(16)//'20bb7'
s.codePointAt(2).toString(16)//'61'
codePointAt(2)获取的是a,但是我们总是觉得a的索引应该是1,那么可以使用for…of循环
var s = '吉a'
for(let ch of s){
console.log(ch.codePointAt(0).toString(16)
}
codePointAt妙用
判断一个字符是两个字节还是四个字节
function is32Bit(c){
return c.codePointAt(0)>0xFFFF
}
is32Bit('吉')//true
is32Bit('a')//false
String.fromCodePoint()
作用与codePointAt()相反
String.fromCodePoint(0x20BB7)
// '吉'
String.fromCodePoint(0x78,0x1f680,0x79) === 'x\uD83D\uDE80y'
//true
第二个代码证明,fromCodePoint()方法如果有多个参数,会被合并成一个字符串返回。
注意,fromCodePoint方法定义在String对象上,而codePointAt是定义在字符串的实例对象上
for…of和for
var text = String.fromCodePoint(0x20BB7)
for(let i=0;i<text.length;i++){
console.log(text[i])
}
// ' '
// ' '
for(let i of text){
console.log(i)
}
//'吉'
text只有一个字符,‘吉’,但是for循环认为他有两个字符,原因是因为他是4个字节,普通一个字符都是两个字节,但是这个字符有四个字节,所以被for循环认为是两个字符,不足为奇,但是for…of像是拥有火眼睛睛一样,发现了这个问题。
at()
charAt() 方法可返回指定位置的字符,返回的字符是长度为 1 的字符串
'abc'.charAt(0)//'a'
'吉'.charAt(0) //'UD842'
上面的代码中,charAt返回的是’吉’的UTF-16编码的第一个字节,实际上是无法显示整个‘吉’,目前,有个提案,用at(),可以识别unicode编码号大于0xFFFF的字符,返回正确的字符
'abc'.at(0) //'a'
'吉'.at(0) //'吉'
normalize()
欧洲语言有语调符号或者重音符号,他们的一个字符可能要通过两个字符拼接形成,举个例子,就像我们的汉字,一个汉字包括两个部分,字和拼音,为了让字和拼音组成一个整体,并且这个整体的length是1,ES6是提出normalize方法
'\u01D1'.normalize() === '\u004F\u030C'.normalize()
//true
NFC,标准等价合成,(举例,把汉字和拼音合成为一个中文字符)
NFD,标准等价分解,(举例,把一个中文拆为汉字和拼音)
'\u004F\u030C'.normalize('NFC').length//1
'\u004F\u030C'.normalize('NFD').length//2
includes()、startWith()、endsWith
var s = 'hello world'
s.startsWith('hello')//true
s.endsWith('d')//true
s.includes('o')//true
这三个方法都支持第二个参数,表示开始搜索的位置
var s = 'hello world'
console.log(s.startsWith('world',6))//true
console.log(s.endsWith('hello',5))//true
console.log(s.includes('o',8))//false
startsWith和endsWith是从第n个位置开始到字符串结束位置之间的字符,搜索方向从前往后,endsWith是前n个字符,方向向前。
以上内容是看阮一峰老师笔记的总结