ES6入门教程02
# 字符串的扩展
# Unicode表示法
# 遍历器接口
# U+2028和U+2029
# JSON.stringify()
# 模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
$('#list').html(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`);
2
3
4
5
6
可以使用 trim()
方法消除
$('#list').html(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`.trim());
2
3
4
5
6
变量使用
模板字符串中嵌入变量,需要将变量名写在${}
之中,大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"
`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"
let obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"
2
3
4
5
6
7
8
9
10
11
12
且可以调用函数
function fn() {
return "Hello World";
}
`foo ${fn()} bar`
// foo Hello World bar
2
3
4
5
6
如果模板字符串中的变量没有声明,将报错。
// 变量place没有声明
let msg = `Hello, ${place}`;
// 报错
2
3
由于模板字符串的大括号内部,就是执行 JavaScript 代码,因此如果大括号内部是一个字符串,将会原样输出。
`Hello ${'World'}`
// "Hello World"
2
模板字符串甚至还能嵌套。
const tmpl = addrs => `
<table>
${addrs.map(addr => `
<tr><td>${addr.first}</td></tr>
<tr><td>${addr.last}</td></tr>
`).join('')}
</table>
`;
2
3
4
5
6
7
8
上面代码中,模板字符串的变量之中,又嵌入了另一个模板字符串,使用方法如下。
const data = [
{ first: '<Jane>', last: 'Bond' },
{ first: 'Lars', last: '<Croft>' },
];
console.log(tmpl(data));
// <table>
//
// <tr><td><Jane></td></tr>
// <tr><td>Bond</td></tr>
//
// <tr><td>Lars</td></tr>
// <tr><td><Croft></td></tr>
//
// </table>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
如果需要引用模板字符串本身,在需要时执行,可以写成函数。
let func = (name) => `Hello ${name}!`;
func('Jack') // "Hello Jack!"
2
上面代码中,模板字符串写成了一个函数的返回值。执行这个函数,就相当于执行这个模板字符串了。
# 模板编译
# 模板标签
模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。
alert`hello`
// 等同于
alert(['hello'])
2
3
标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。
但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
let a = 5;
let b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);
2
3
4
5
6
上面代码中,模板字符串前面有一个标识名tag
,它是一个函数。整个表达式的返回值,就是tag
函数处理模板字符串后的返回值。
函数tag
依次会接收到多个参数。
function tag(stringArr, value1, value2){
// ...
}
// 等同于
function tag(stringArr, ...values){
// ...
}
2
3
4
5
6
7
8
9
tag
函数的第一个参数是一个数组,该数组的成员是模板字符串中那些没有变量替换的部分,也就是说,变量替换只发生在数组的第一个成员与第二个成员之间、第二个成员与第三个成员之间,以此类推。
tag
函数的其他参数,都是模板字符串各个变量被替换后的值。由于本例中,模板字符串含有两个变量,因此tag
会接受到value1
和value2
两个参数。
tag
函数所有参数的实际值如下。
- 第一个参数:
['Hello ', ' world ', '']
- 第二个参数: 15
- 第三个参数:50
也就是说,tag
函数实际上以下面的形式调用。
tag(['Hello ', ' world ', ''], 15, 50)
我们可以按照需要编写tag
函数的代码。下面是tag
函数的一种写法,以及运行结果。
let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;
function passthru(literals) {
let result = '';
let i = 0;
while (i < literals.length) {
result += literals[i++];
if (i < arguments.length) {
result += arguments[i];
}
}
return result;
}
msg // "The total is 30 (31.5 with tax)"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
函数接收的第一个参数是根据变量的位置划分的
if(i < arguments.length){
//此处+变量划分处的变量
}
2
3
实际应用例子:防止用户恶意输出标签
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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18