Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

JavaScript 字符串模板

  前几天我还刚在抱怨 Chrome 怎么还不放出字符串模板的支持。今天打开 Chrome 发现控制台的 DOM 变化加了特技,于是我猜 Chrome 又更新了,试了试字符串模板,果真还支持上了!至此 FF 和 Chrome 的稳定版都支持了,那就让我们来尝一口吧!
  一直以来 JavaScript 的字符串都是以引号来包裹的,现在引入了字符串模板后多出了一种字符串词法 —— 使用重音符「`」来包裹。并且和传统的字符串不同,重音符包裹的字符串内是可以直接带换行的,也就是多行字符串。不过这点暂时先放在,这篇文章主要介绍的是字符串模板的「模板」。
  所谓模板,就是在一个字符串中放置各种标签。模板引擎会接收一组数据,并且把模板中的标签替换为最终数据。在此之前,我们都是自己实现字符串模板的。比如使用正则来匹配模板内的标签,使用 Function 来解析标签内的表达式。 <script>
// 准备模板和数据
var template="{a} + {b} = {a+b}";
var data={a:1,b:2};

// 模板引擎的动作
var keys=[],values=[];
for(var i in data)keys.push(i),values.push(data[i]);
var result=template.replace(/\{(.*?)\}/g,function($0,$1){
  return new Function(keys,"return ("+$1+")").apply(null,values);
});

// 1 + 2 = 3
alert(result);
</script>
  字符串模板就自带了这个过程,我们可以这么写 <script>
// 准备数据
var data={a:1,b:2};

// 1 + 2 = 3
alert(`${data.a} + ${data.b} = ${data.a+data.b}`);
</script>
  这些 ${xxx} 都会被替换为 xxx 表达式的值。
  字符串模板的字面量同对象和数组字面量一样,都是每次执行到时生成新实例。也就是说如果它里面包含了一个循环变量是会根据循环个更新的,并且如果没有执行到则不会处理表达式。 <script>
// 循环可以正确输出
for(var i=0;i<3;i++)console.log(`i=${i}`);
if(0)`${alert("这个 alert 不会被执行,因为字符串词法没被执行到。")}`;
</script>
  其实字符串模板内的表达式执行所在的作用域就是当前作用域,这个作用域甚至可以精确到 block scope,这里就不贴代码了。
  另外,字符串模板还有更诡异的 tag 用法,感觉它在颠覆传统的函数调用语法。传统的函数调用都是在一个函数后面放一对小括号,里面再放入参数。而现在呢?有这样的用法 <script>
// 定义一个函数
var tag=function(){ console.log(arguments); };

// 这个函数被调用了,并且传入了一堆奇怪的东西作为参数
tag `${1} + ${2} = ${1+2}`;
</script>
  arguments[0] 是字符串模板以标签 split 的数组,后面参数是标签内表达式解析后的各个结果按顺序的排列。其实对于这个 tag 函数还有提供一个原生的 String.raw,但具体我已经不想说啥,感觉被恶心到了。
  这一整套概念倒不难理解,但设计理念我是完全无法理解了。解决「字符串模板」这种函数级的问题居然搞了这么一套恶心的词法级的方案也真是醉了。我觉得除了「多行字符串」外其它所有设定都是多余的!
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^