ECMA Script 6_字符串_扩展_字符 是4字节还是2字节?_模板字符串
ES6 字符串扩展
ES6 加强了对 Unicode 的支持,并且扩展了字符串对象
- 字符 的 Unicode 表示法
允许采用 \uxxxx 形式表示一个字符,
其中 xxxx 表示字符的 Unicode 码点
- 这种表示法只限于码点在 \u0000 ~ \uFFFF 之间的字符。
- "\u0061" // "a"
- 超出这个范围的字符,必须用两个双字节的形式表示
- "\uD842\uDFB7" // "𠮷"
- \u 后面的码点 超过0xFFFF的数值(比如\u20BB7),JavaScript 会理解成\u20BB+7。
- 由于 \u20BB 是一个不可打印字符,所以只会显示一个空格,后面跟着一个 7
- "\u20BB7" // " 7"
- ES6 对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符,而无须双字节
- "\u{20BB7}" // "𠮷"
- "\u{41}\u{42}\u{43}" // "ABC"
- let hello = 123;
- hell\u{6F} // 123
- console.log('\u{1F680}' === '\uD83D\uDE80'); // true
- 所以,在 ES6 中,共有 6 中方式表示一个字符
-
console.log('\z' === 'z'); // true console.log('\172' === 'z'); // true console.log('\x7A' === 'z'); // true console.log('\u007A' === 'z'); // true console.log('\u{7A}' === 'z'); // true
- ES6 提供了
codePointAt
方法,能够正确处理 4 个字节储存的字符,返回一个字符的码点 -
let s = '𠮷a'; s.codePointAt(0); // 134071 s.codePointAt(1); // 57271 s.codePointAt(2); // 97
总之,codePointAt
方法会正确返回 32 位的 UTF-16 字符的码点。
对于那些两个字节储存的常规字符,它的返回结果与 charCodeAt
方法相同
- codePointAt 方法返回的是码点的十进制值,如果想要十六进制的值,可以使用 toString 方法转换一下
-
let s = '𠮷a'; s.codePointAt(0).toString(16); // "20bb7" s.codePointAt(2).toString(16); // "61"
- 测试一个字符由两个字节还是由四个字节组成的
-
function is32Bit(c) { return c.codePointAt(0) > 0xFFFF; } is32Bit("𠮷"); // true is32Bit("a"); // false
- ES6 提供了 String.fromCodePoint() 方法,可以识别大于 0xFFFF 的字符,弥补了 String.fromCharCode 方法的不足
-
String.fromCodePoint(0x20BB7); // "𠮷" console.log(String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'); // true
- ES6 对数组扩展了 对字符串包含问题的 API
-
let str = 'Hello world!'; str.startsWith('Hello'); // true 是否以 'Hello' 开头 str.endsWith('!'); // true 是否以 '!' 结尾 str.includes('o'); // true 是否包含 'o'
支持 两个参数
-
let str = 'Hello World!'; str.startsWith('world', 6); // true 从第 n 个开始,之后字符串 是否以 world' 开头 str.endsWith('Hello', 5); // true 从第 n 个开始,之前的字符串 是否以 'Hello' 结尾 str.includes('Hello', 6); // false 从第 n 个开始,之后的字符串 是否包含 'Hello'
- str.repeat(2); // ES6 扩展 API,将 str 重复 2 次返回新字符串,而不影响 原字符串 str
如果传入参数为小数,则向下取整
-
'na'.repeat(2.9); // "nana" 等同于 'na'.repeat(2) // 负数, 或者 infinity 会报错 'na'.repeat(Infinity); // RangeError 'na'.repeat(-1); // RangeError
如果是字符串,则转换为 Number 类型
-
'na'.repeat('na'); // "" 'na'.repeat('3'); // "nanana" 'na'.repeat(NaN); // "" 相当于 0 'na'.repeat(-0.9); // "" -1 到 0 之间,相当于 0
- ES6 引入字符串补全长度的功能,从头补全 str.padStart(),或者从尾补全 str.padEnd()
第一个参数 指定最大字符串长度,第二个参数用于补全的字符串
-
'x'.padStart(5, 'ab'); // 'ababx' 'x'.padStart(4, 'ab'); // 'abax' 'x'.padEnd(5, 'ab'); // 'xabab' 'x'.padEnd(4, 'ab'); // 'xaba'
如果 最大长度 大于 原字符串,则补全不生效,返回原字符串
-
'abc'.padStart(2, 'ab'); // 'abc' 'ccc'.padEnd(2, 'ab'); // 'ccc'
如果省略第二个用于补全的字符串,则 默认以空格补全
-
'a'.padStart(4); // ' a' 'b'.padEnd(4); // 'b '
- 应用:
- 为数值补全指定位数。下面代码生成 10 位的数值字符串
-
'1'.padStart(10, '0'); // "0000000001" '12'.padStart(10, '0'); // "0000000012" '123456'.padStart(10, '0'); // "0000123456"
- 生成 字符串格式。
-
'12'.padStart(10, 'YYYY-MM-DD'); // "YYYY-MM-12" '09-12'.padStart(10, 'YYYY-MM-DD'); // "YYYY-09-12"
- ES6 引入了模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。
它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量
模板字符串的大括号内部,就是执行 JavaScript 代码,因此如果大括号内部是一个字符串,将会原样输出
-
// 普通字符串 `In JavaScript '\n' is a line-feed.` // 多行字符串 `In JavaScript this is not legal.` console.log(`string text line 1 string text line 2`); // 字符串中嵌入变量 let name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?` // 变量必须写在 `${}` 里面
如果在模板字符串中需要使用反引号,则前面要用反斜杠转义
-
let greeting = `\`Yo\` World!`;
模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中
-
$('#list').html(` <ul> <li>first</li> <li>second</li> </ul> `);
花括号内 可以放入表达式,进行计算
-
let x = 1; let y = 2; console.log(`${x} + ${y} = ${x + y}`); // "1 + 2 = 3" console.log(`${x} + ${y * 2} = ${x + y * 2}`); // "1 + 4 = 5" let obj = {x: 1, y: 2}; console.log(`${obj.x + obj.y}`); // "3"
模板字符串之中还能调用函数
-
function fn() { return "Hello World"; } console.log(`foo ${fn()} bar`); // foo Hello World bar
- 标签模板: 特别的函数调用方式
-
let a = 5; let b = 10; function tag(s, v1, v2) { console.log(s[0]); console.log(s[1]); console.log(s[2]); console.log(s[3]); console.log(v1); console.log(v2); return "OK"; } console.log(tag`Hello ${ a + b } world ${ a * b}RyenToretto`); // "Hello " // " world " // RyenToretto" // "" // 15 // 50 // "OK"
应用:
- 就是过滤 HTML 字符串,防止用户输入恶意内容
-
let message = SaferHTML`<p>${sender} has sent you a message.</p>`; function SaferHTML(templateData) { let s = templateData[0]; for (let i = 1; i < arguments.length; i++) { let 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; };
ES6 还为原生的 String 对象,提供了一个 raw
方法——模板字符串的处理函数
将所有变量替换,而且对斜杠进行转义,方便下一步作为字符串来使用
- 返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串
-
String.raw`Hi\n${2+3}!`; // 返回 "Hi\\n5!" String.raw`Hi\u000A!`; // 返回 "Hi\\u000A!"
即使 原字符串的斜杠已经转义,String.raw() 还是
会进行再次转义
--------小尾巴
________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...