@@ -318,13 +318,117 @@ var msg = `Hello, ${place}`;
318318// 报错
319319```
320320
321- 由于模板字符串的大括号内部,就是执行JavaScript代码,因此如果表达式放在引号之中 ,将会原样输出。
321+ 由于模板字符串的大括号内部,就是执行JavaScript代码,因此如果大括号内部是一个字符串 ,将会原样输出。
322322
323323``` javascript
324324` Hello ${ ' World' } `
325325// "Hello World"
326326```
327327
328+ ## 实例:模板编译
329+
330+ 下面,我们来看一个通过模板字符串,生成正式模板的实例。
331+
332+ ``` javascript
333+ var template = `
334+ <ul>
335+ <% for(var i=0; i < data.supplies.length; i++) {%>
336+ <li><%= data.supplies[i] %></li>
337+ <% } %>
338+ </ul>
339+ ` ;
340+ ```
341+
342+ 上面代码在模板字符串之中,放置了一个常规模板。该模板使用` <%...%> ` 放置JavaScript代码,使用` <%= ... %> ` 输出JavaScript表达式。
343+
344+ 怎么编译这个模板字符串呢?
345+
346+ 一种思路是将其转换为JavaScript表达式字符串。
347+
348+ ``` javascript
349+ echo (' <ul>' );
350+ for (var i= 0 ; i < data .supplies .length ; i++ ) {
351+ echo (' <li>' );
352+ echo (data .supplies [i]);
353+ echo (' </li>' );
354+ };
355+ echo (' </ul>' );
356+ ```
357+
358+ 这个转换使用正则表达式就行了。
359+
360+ ``` javascript
361+ var evalExpr = / <%=(. +? )%>/ g ;
362+ var expr = / <%([\s\S ] +? )%>/ g ;
363+
364+ template = template
365+ .replace (evalExpr, ' `); \n echo( $1 ); \n echo(`' )
366+ .replace (expr, ' `); \n $1 \n echo(`' );
367+
368+ template = ' echo(`' + template + ' `);' ;
369+ ```
370+
371+ 然后,将` template ` 封装在一个函数里面返回,就可以了。
372+
373+ ``` javascript
374+ var script =
375+ ` (function parse(data){
376+ var output = "";
377+
378+ function echo(html){
379+ output += html;
380+ }
381+
382+ ${ template }
383+
384+ return output;
385+ })` ;
386+
387+ return script;
388+ ```
389+
390+ 将上面的内容拼装成一个模板编译函数` compile ` 。
391+
392+ ``` javascript
393+ function compile (template ){
394+ var evalExpr = / <%=(. +? )%>/ g ;
395+ var expr = / <%([\s\S ] +? )%>/ g ;
396+
397+ template = template
398+ .replace (evalExpr, ' `); \n echo( $1 ); \n echo(`' )
399+ .replace (expr, ' `); \n $1 \n echo(`' );
400+
401+ template = ' echo(`' + template + ' `);' ;
402+
403+ var script =
404+ ` (function parse(data){
405+ var output = "";
406+
407+ function echo(html){
408+ output += html;
409+ }
410+
411+ ${ template }
412+
413+ return output;
414+ })` ;
415+
416+ return script;
417+ }
418+ ```
419+
420+ ` compile ` 函数的用法如下。
421+
422+ ``` javascript
423+ var parse = eval (compile (template));
424+ div .innerHTML = parse ({ supplies: [ " broom" , " mop" , " cleaner" ] });
425+ // <ul>
426+ // <li>broom</li>
427+ // <li>mop</li>
428+ // <li>cleaner</li>
429+ // </ul>
430+ ```
431+
328432## 标签模板
329433
330434模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。
0 commit comments