ES6 随记(3.1)-- 字符串的拓展
上一章请见:
4. 拓展
a. 字符串的拓展
有些字符需要 4 个字节储存,比如 \uD83D\uDE80 才代表“𠮷”(不是吉祥的吉),
它的 length / for-in / charAt / charCodeAt 都是有问题的,所以 ES6 完善了这类 UTF-16 的字符问题。
还有以下其他扩展:
1 可将码点放入大括号。\u{20BB7} 可以让 Unicode 拥有五位字符了,即: '\uD842\uDFB7' === '\u{20BB7}';
2 codePointAt()。 返回十进制的码点,不过奇葩的是,该 UTF-16 的字符还是两位,所以 '𠮷'.codePointAt(0) 为该字符的码点,'𠮷'.codePointAt(1) 为后一字节的码点
3 String.fromCharPoint()。将码点转化为字符,也是旨在解决 UTF-16 的问题。
4 为字符串添加了 Iterator 遍历器,也就是可以使用 for-of 遍历,不像 for-in 那种按字节遍历,而是按字符遍历,也就是 '𠮷' 不会被遍历成两个了
5 normalize。Ǒ的 \u004F 和 \u004F\u030C 两种形态将可以被等价 (无需了解,主要用于欧洲词汇)
6 includes。indexOf 负责找到索引位置,返回数字,includes 判断有无,返回 boolean。
7 startsWith | endsWidth。判断以某字符开头/结尾,返回 boolean
8 repeat。重复字符串,如 console.log('x'.repeat(3)); // xxx
9 padStart | padEnd。将字符串填充到目标字符串前面/后面,直到长度满足。如: console.log('abc'.padStart(10, '01234566789')); // 0123456abc
特别提一提,特殊字符串 ``
· 多行/动态字符串。使用 ``(tab键上面那个) 包裹字符串,字符串就可以不用每行都封闭引号了
· 模板字符串。也称动态字符串,即: var name = 'x'; `<div>${name}</div>`这种 MVVM 的模板式类似写法(${变量})。且内部还可以进行运算和函数运行。
const tmpl = addrs => ` <table> ${addrs.map(addr => ` <tr><td>${addr.first}</td></tr> <tr><td>${addr.last}</td></tr> `).join('')} </table> `; const data = [ { first: '<Jane>', last: 'Bond' }, { first: 'Lars', last: '<Croft>' }, ]; console.log(tmpl(data));
附带一提,String.row() 可以将上述模板字符串转为解析后的常规字符串。
另一方面,还有个标签模板的运用:
// 下式等同于:alert(123) alert`123`; const a = 5, b = 10; // 下式等同于:tag(['Hello ', ' world ', ''], 15, 50); tag`Hello ${ a + b } world ${ a * b }.`; // 下式等同于:function tag(stringArr, value1, value2) {} function tag(stringArr, ...values) { let output = ""; for (var index = 0; index < values.length; index++) { output += stringArr[index] + values[index]; } output += stringArr[index] console.log(output) return output; // 输出 Hello 15 world 50. }
此功能的作用在于,你可以定义一个 jsx 方法来加入 #for-in 呀,或者定义一个 java 方法来运行 class。此节不如还是看原著吧
至于模板字符串的限制个人还接触不到,主要是嵌入其他语言,和标签模板已转义的问题,略过不表。
本文部分转载自 阮一峰 的 ECMAScript 6 入门