ES6对字符串进行了一些扩展,主要表现在对Unicode 大于\uFFFF的字符的处理上。
1. ES6中字符的Unicode表示方法
在ES5中,字符串的Unicode表示方法: \uxxxx 。 xxxx表示字符的码点,这种表示仅限于\u0000 到 \uFFFF 之间的字符,超出的需要用双字节来表示。
在ES6中,对字符串的Unicode表示方法进行了改进,将码点放入大括号即可:
"\u{20BB7}" // "?" "\u{41}\u{42}\u{43}" // "ABC" let hello = 123; hell\u{6F} // 123 '\u{1F680}' === '\uD83D\uDE80' // true
有了这一种方法之后,JavaScript一共有6种方式可以表示一个字符:
'\z' === 'z' // true '\172' === 'z' // true '\x7A' === 'z' // true '\u007A' === 'z' // true '\u{7A}' === 'z' // true
2.ES6中对码点和字符转换的方法扩展
(1)''.codePointAt() 替代 ''.charCodeAt()
2
个字节。对于那些需要
4
个字节储存的字符(Unicode码点大于
0xFFFF
的字符),JavaScript会认为它们是两个字符。
4
个字节的字符,JavaScript不能正确处理,字符串长度会误判为
2
,而且
charAt
方法无法读取整个字符,
charCodeAt
方法只能分别返回前两个字节和后两个字节的值。
codePointAt
方法,能够正确处理4个字节储存的字符,返回一个字符的码点 :
var s = '?a'; s.codePointAt(0) // 134071 s.codePointAt(1) // 57271 s.codePointAt(2) // 97
codePointAt
方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString
方法转换一下。
在上面的例子中,codePointAt
方法的参数,仍然是不正确的。比如,上面代码中,字符
a
在字符串
s
的正确位置序号应该是1,但是必须向
codePointAt
方法传入2。解决这个问题的一个办法是使用
for...of
循环,因为它会正确识别32位的UTF-16字符。
codePointAt
方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。
(2)String.fromCodePoint() 替代 String.fromCharCode()
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); } // "?"
(4)其他有用的方法扩展
var s = 'Hello world!'; s.startsWith('Hello') // true s.endsWith('!') // true s.includes('o') // true
var s = 'Hello world!'; s.startsWith('world', 6) // true s.endsWith('Hello', 5) // true s.includes('Hello', 6) // false
'x'.repeat(3) // "xxx" 'hello'.repeat(2) // "hellohello" 'na'.repeat(0) // ""
'x'.padStart(5, 'ab') // 'ababx' 'x'.padStart(4, 'ab') // 'abax' 'x'.padEnd(5, 'ab') // 'xabab' 'x'.padEnd(4, 'ab') // 'xaba'
(5)模板字符串
模板字符串是增强版的字符串,使用反引号(`)进行标识, 它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。 如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
// 普通字符串 `In JavaScript '\n' is a line-feed.` // 多行字符串 `In JavaScript this is not legal.` console.log(`string text line 1 string text line 2`); // 字符串中嵌入变量 var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?`
模板字符串可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。
alert`123` // 等同于 alert(123)
“标签模板”的一个重要应用,就是过滤HTML字符串,防止用户输入恶意内容。
var message = SaferHTML`<p>${sender} has sent you a message.</p>`; function SaferHTML(templateData) { var s = templateData[0]; for (var i = 1; i < arguments.length; i++) { var arg = String(arguments[i]); // Escape special characters in the substitution. s += arg.replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">"); // Don't escape special characters in the template. s += templateData[i]; } return s; }
但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
标签模板里面,可以内嵌其他语言。但是,模板字符串默认会将字符串转义,因此导致了无法嵌入其他语言。