目录
Watch out!
首页 web前端 js教程 详解JavaScript ES6中的模板字符串_基础知识

详解JavaScript ES6中的模板字符串_基础知识

May 16, 2016 pm 03:48 PM
javascript

在 ES6 中引入了一种新的字符串字面量 — 模板字符串,除了使用反引号 (`) 表示,它们看上去和普通的字符串没有什么区别。在最简单的情况下,他们就是普通的字符串:

context.fillText(`Ceci n'est pas une cha?ne.`, x, y);
 
context.fillText(`Ceci n'est pas une cha?ne.`, x, y);
登录后复制

之所以被称为模板字符串,是因为模板字符串为 JS 引入了简单的字符串插值特性,也就是说,可以方便优雅地将 JS 的值插入到字符串中。

很多地方可以用到模板字符串,看下面这个不起眼的错误提示消息:

function authorize(user, action) {
 if (!user.hasPrivilege(action)) {
  throw new Error(
   `User ${user.name} is not authorized to do ${action}.`);
 }
}
 
function authorize(user, action) {
 if (!user.hasPrivilege(action)) {
  throw new Error(
   `User ${user.name} is not authorized to do ${action}.`);
 }
}
登录后复制

上面代码中,${user.name} 和 ${action} 被称为模板占位符,JavaScript 将把 user.name和 action 的值分别插到对应的位置上,然后生成像这样 “User jorendorff is not authorized to do hockey.” 的字符串。

现在,我们看到了一个比 + 运算符更优雅的语法,下面是一些你期待的特性:

模板占位符可以是任何 JavaScript 表达式,所以函数调用和四则运算等都是合法的。(甚至你还可以在一个模板字符串中嵌套另一个模板字符串。)
如果一个值不是字符串,它将被转换为字符串。例如,如果 action 是一个对象,那么该对象的 .toString() 将被调用,来将其转换为字符串。
如果你想在模板字符串中使用反引号,你需要使用反斜杠 \ 将其转义。
同样地,如果想在模板字符串中输出 ${,也需要使用反斜杠将其转义:${ 或 $\{。
模板字符串可以跨越多行:

$("#warning").html(`
 <h1 id="Watch-out">Watch out!</h1>
 <p>Unauthorized hockeying can result in penalties
 of up to ${maxPenalty} minutes.</p>
`);
 
$("#warning").html(`
 <h1 id="Watch-out">Watch out!</h1>
 <p>Unauthorized hockeying can result in penalties
 of up to ${maxPenalty} minutes.</p>
`);

登录后复制

模板字符串中所有的空格、换行和缩进,都将被原样输出到结果字符串中。

下面我们来看看模板字符串做不到的事情:

不会自动转义特殊字符,为了避免跨站脚本漏洞,你还是需要小心对待不可信的数据,这一点上与普通字符串一样。
不能与国际化库配合使用,不处理特殊语言格式的数字、日期等。
不是模板引擎(比如 MustacheNunjucks)的替代品。模板字符串没有处理循环的语法 — 不能通过一个数组构建出一个表格(table)。

为了解决这些限制,ES6 为开发者和库设计者提供了另一种模板字符串 — 标签模板。

标签模板的语法很简单,只需要在开始的反引号前引入一个标签。看第一个例子:SaferHTML,我们要使用这个标签模板来解决上述的第一个限制:自动转义特殊字符。

需要注意的是,SaferHTML 方法并不是 ES6 标准库提供的,我们需要自己来实现:

var message =
 SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`;
 
var message =
 SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`;
登录后复制

这里的 SaferHTML 标签是单个标识符,标签也可以是属性,比如 SaferHTML.escape,甚至还可以是方法调用:SaferHTML.escape({unicodeControlCharacters: false})。准确地说,任何 ES6 的成员表达式或调用表达式都可以作为标签。

可以看出,模板字符串仅仅是字符串连接的语法糖,而标签模板确是一个完全不同的东西:函数调用。

所以,上面代码等价于:

var message =
 SaferHTML(templateData, bonk.sender);
 
var message =
 SaferHTML(templateData, bonk.sender);
登录后复制

其中 templateData 是一个不可变的字符串数组,由 JS 引擎基于源模板字符串生成,这里的数组含有两个元素,因为模板字符串被占位符分隔后含有两个字符串,因此,templateData 将是这样: Object.freeze(["

", " has sent you a bonk.

"]

(事实上,templateData 上还有另一个属性:templateData.raw,本文并深入不讨论该属性。该属性的值也是一个数组,包含了标签模板中所有的字符串部分,但字符串中包含了转义序列,看上去更像源代码中的字符串,比如 \n。ES6 的内置标签 String.raw 将使用这些字符串。)

这就使得 SaferHTML 方法可以随意解析这两个字符串,存在 N 中替换方式。

在继续阅读钱,你可能在苦苦思索如何实现 SaferHTML 方法。

下面是一种实现(gist):

function SaferHTML(templateData) {
 var s = templateData[0];
 for (var i = 1; i < arguments.length; i++) {
  var 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;
}
 
function SaferHTML(templateData) {
 var s = templateData[0];
 for (var i = 1; i < arguments.length; i++) {
  var 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;
}

登录后复制

有了上面的方法,即使使用一个恶意的用户名,用户也是安全的。

一个简单的例子并不足以说明标签模板的灵活性,让我们重温一下上面列举的模板字符串的限制,看看我们还可以做些什么。

模板字符串不会自动转义特殊字符,但是我们可以通过标签模板来解决这个问题,事实上我们还可以将 SaferHTML 这个方法写的更好。从安全角度来看,这个 SaferHTML 非常脆弱。在 HTML 中,不同的地方需要用不同的方式去转义,SaferHTML 并没有做到。稍加思考,我们就可以实现一个更加灵活的 SaferHTML方法,能够将 templateData 中的任何一个 HTML 转义,知道哪个占位符是纯 HTML;哪个是元素的属性,从而需要对 ' 和 " 转义;哪个是 URL 的 query 字符串,从而需要用 URL 的 escaping 方法,而不是 HTML 的 escaping;等等。这似乎有些牵强,因为 HTML 转义效率比较低。辛运是的,标签模板的字符串是保持不变的,SaferHTML 可以缓存已经转义过的字符串,从而提高效率。
模板字符串并没有内置的国际化特性,但通过标签模板,我们可以添加该特性。Jack Hsu 的文章详细介绍了实现过程,看下面例子:

i18n`Hello ${name}, you have ${amount}:c(CAD) in your bank account.`
// => Hallo Bob, Sie haben 1.234,56 $CA auf Ihrem Bankkonto.




i18n`Hello ${name}, you have ${amount}:c(CAD) in your bank account.`
// => Hallo Bob, Sie haben 1.234,56 $CA auf Ihrem Bankkonto.

登录后复制

上面例子中的 name 和 amount 很好理解,将被 JS 引擎替换为对应的字符串,但是还有一个没有见过的占位符::c(CAD),这将被 i18n 标签处理,从 i18n 的文档可知::c(CAD)表示 amount 是加拿大美元货币值。

模板字符串不能替代 Mustache 和 Nunjucks 这类模板引擎,部分原因在于模板字符串不支持循环和条件语句。我们可以编写一个标签来实现这类功能:

// Purely hypothetical template language based on
// ES6 tagged templates.
var libraryHtml = hashTemplate`
 <ul>
  #for book in ${myBooks}
   <li><i>#{book.title}</i> by #{book.author}</li>
  #end
 </ul>
`;

 
// Purely hypothetical template language based on
// ES6 tagged templates.
var libraryHtml = hashTemplate`
 <ul>
  #for book in ${myBooks}
   <li><i>#{book.title}</i> by #{book.author}</li>
  #end
 </ul>
`;

登录后复制

灵活性还不止于此,需要注意的是,标签函数的参数不会自动转换为字符串,参数可以是任何类型,返回值也一样。标签模板甚至可以不需要字符串,你可以使用自定义标签来创建正则表达式、DOM 树、图片、代表整个异步进程的 Promise、JS 数据结构、GL 着色器…

标签模板允许库设计者创建强大的领域特定语言。这些语言可能看上去并不像 JS,但他们可以无缝嵌入到 JS 中,并且可以与语言的其余部分进行交互。顺便说一下,我还没有在其他语言中见过类似的特性,我不知道这个特性讲给我们带来些什么,但各种可能性还是非常令人兴奋的。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

如何在JavaScript中获取HTTP状态码的简单方法 如何在JavaScript中获取HTTP状态码的简单方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

See all articles