Unicode表示法
Javascript允许采用\uxxxx
以十六进制码nnnn表示一个Unicode字符,但只能表示范围在\u0000 ~ \uFFFF之间的字符,超过这个范围的字符的范围,则必须使用双字节的形式表示
"\uD842\uDFB7"
// '吉'
在ES6中,只要将其放进大括号内,就可以用一个字节表示
"u\{20BB7}"
// '吉'
"\u{41}\u{42}\u{43}"
//'ABC'
codePointAt() 和 String.fromCodePoint()
在ES5中,字符使用UTF-16格式保存,也就是一个字符用固定2字节存储,charCodeAt()
方法和String.fromCharCode()
方法来分别获取一个字符的字符编码和将字符编码转换为字符,但它们不能识别使用4字节存储的字符,Javascript会将其识别为两个字符。
codePointAt()
方法能够正确返回4个字节存储的字符,并返回其unicode码(默认为十进制,可以调用toString(16)
方法返回16进制值)
上述代码将字符串视作3个字符,在第一个字符上,正确地识别了unicode码,但是字符“a”
的位置序号却成了3,对于这个问题,可以使用for...of
循环,它会正确识别32位的4字节UTF-16字符
相应的,String.fromCodePoint()
方法能将超过0xFFFF的字符编码转换为字符
字符串的遍历
使用for...of
可以正确识别遍历字符串
for (let s of "abc"){
console.log(s);
}
//a
//b
//c
at()
ES5的charAt()
方法,返回字符串给定位置的字符,但其同样不能识别unicode码超过0xFFFF的字符,at()
方法弥补了这问题
normalize()
该方法将字符的不同表示方法统一为同样的形式,该方法可以接受一个参数,用于指定正规化的方法(NFC,NFD,NFKC,NFKD)
'\u01D1' === '\u004F\u030C' //false
'\u01D1'.normalize() === '\u004F\u030C'.normalize() //true
值得注意的是,该方法不能识别3个及以上字符的合成,且应与DOM的normalize()
方法区别,后者在包含多个文本节点的父元素上调用,其会将空白文本节点移除,并合并相邻的文本节点。
includes(), startsWith(), endsWith()
ES5提供了indexOf
方法来查找字符串的位置,ES6又提供了3种新方法:
includes()
:返回布尔值,表示是否找到了参数字符串startsWith()
:返回布尔值,表示参数字符串是否在源字符串开头endsWith()
:返回布尔值,表示参数字符串是否在源字符串结尾
它们都可接受第二个可选参数n,表示开始搜索的位置,其中endsWith()
针对前n个字符,而其余两方法针对从第n个字符到字符串结束的字符
var s = 'hello world';
s.includes('o'); //true
s.startsWith('he'); //true
s.endsWith('d'); //true
repeat()
返回一个新字符串,将原字符串重复多次
'x'.repeat(3) //'xxx'
'a'.repeat(0) //''
参数如果是小数会被取整,如果是小于-1的负数或是无限大,则会报错
padStart() 和 padEnd()
这两个方法用于字符串补全长度,padStart()
用于头部补全,padEnd()
用于尾部补全。他们都接受两个参数,补全后字符串的最小长度和用于补全的字符串,如果省略第二个参数,则会用空格来补全
'x'.padStart(4,'ab'); //'abax'
'x'.padEnd(4,'ab'); //'xaba'
如果原字符串的长度等于或大于指定的最小长度,则返回原字符串
'xxx'.padStart(2,'ab'); //'xxx'
'xxx'.padEnd(2,'ab'); //'xxx'
模板字符串
模板字符串是增强版的字符串,用反引号( ` )标识,可以用其定义多行字符串,或者在字符串中嵌入变量
//多行字符串
` In ES5 this is
not leagl `
在模板字符串中嵌入变量,需要将变量名写在${ }
中
var x = 1;
var y = 2;
`${x} + ${y * 2} = ${x + y}`
//"1+4=3"
var obj = {x:!, y:2};
`${ obj.x + obj.y }`
//3
模板字符串中还能调用函数
function fn(){
return "hello";
}
` zjw, ${fn()} !`
//"zjw, hello !"
标签模板
模板字符串可以紧跟在一个函数后面,这个函数用于处理这个模板字符串,这称为标签模板
alert`123`
//等同于 alert(123)
当模板字符串中有变量时,模板字符串会被分隔成几部分,并将分隔后的纯字符串数组和变量参数传递给函数
var a=5;
var b=10;
tag`hello ${a + b} world ${ a*b }`;
//等同于
tag(['hello ',' world '], 15, 50);
function tag(stringArr,value1,value2){
//处理字符串
}
标签模板可以用于过滤HTML字符串,多语言转换等
var message = SaferHTML`<p>${user} has send you a message.</p>`
function SaferHTML(data){
var s = data[0];
for (var i = 1; i < arguments.length; i++){
var arg = String(arguments[i]); //将用户的输入转换为字符串
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">"); //转义字符并将其连接到纯字符串后面
s += data[i]; //连接下一个纯字符串
}
return s;
}
String.raw()
该方法往往充当模板字符串的处理函数,其会返回一个转义反斜线,并替换变量后的模板字符串。
String.raw`Hi \n ${2+3}`;
// "Hi \\n 5"
其也可以作为正常函数使用,其第一个参数是一个具有raw属性的对象,且属性值应该是一个数组
String.raw({raw:['a','b','c']},0,1);
//"a0b1c"