diff --git a/docs/string.md b/docs/string.md index b1e575a..ebbeede 100644 --- a/docs/string.md +++ b/docs/string.md @@ -318,13 +318,117 @@ var msg = `Hello, ${place}`; // 报错 ``` -由于模板字符串的大括号内部,就是执行JavaScript代码,因此如果表达式放在引号之中,将会原样输出。 +由于模板字符串的大括号内部,就是执行JavaScript代码,因此如果大括号内部是一个字符串,将会原样输出。 ```javascript `Hello ${'World'}` // "Hello World" ``` +## 实例:模板编译 + +下面,我们来看一个通过模板字符串,生成正式模板的实例。 + +```javascript +var template = ` + +`; +``` + +上面代码在模板字符串之中,放置了一个常规模板。该模板使用`<%...%>`放置JavaScript代码,使用`<%= ... %>`输出JavaScript表达式。 + +怎么编译这个模板字符串呢? + +一种思路是将其转换为JavaScript表达式字符串。 + +```javascript +echo(''); +``` + +这个转换使用正则表达式就行了。 + +```javascript +var evalExpr = /<%=(.+?)%>/g; +var expr = /<%([\s\S]+?)%>/g; + +template = template + .replace(evalExpr, '`); \n echo( $1 ); \n echo(`') + .replace(expr, '`); \n $1 \n echo(`'); + +template = 'echo(`' + template + '`);'; +``` + +然后,将`template`封装在一个函数里面返回,就可以了。 + +```javascript +var script = +`(function parse(data){ + var output = ""; + + function echo(html){ + output += html; + } + + ${ template } + + return output; +})`; + +return script; +``` + +将上面的内容拼装成一个模板编译函数`compile`。 + +```javascript +function compile(template){ + var evalExpr = /<%=(.+?)%>/g; + var expr = /<%([\s\S]+?)%>/g; + + template = template + .replace(evalExpr, '`); \n echo( $1 ); \n echo(`') + .replace(expr, '`); \n $1 \n echo(`'); + + template = 'echo(`' + template + '`);'; + + var script = + `(function parse(data){ + var output = ""; + + function echo(html){ + output += html; + } + + ${ template } + + return output; + })`; + + return script; +} +``` + +`compile`函数的用法如下。 + +```javascript +var parse = eval(compile(template)); +div.innerHTML = parse({ supplies: [ "broom", "mop", "cleaner" ] }); +// +``` + ## 标签模板 模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。