在 JavaScript 中使用反引号字符 (')

在JavaScript中,反引号似乎与单引号的工作方式相同。例如,我可以使用反引号来定义如下字符串:

var s = `abc`;

有没有一种方式,反引号的行为实际上与单个引号的行为不同?


† 请注意,在程序员中,“backtick”是更普遍地称为重音的一个名称。程序员有时也使用替代名称“backquote”和“backgrave”。此外,在Stack Overflow和其他地方,“backtick”的其他常见拼写是“back-tick”和“back tick”。


答案 1

这是一项称为模板文本的功能。

在 ECMAScript 2015 规范的早期版本中,它们被称为“模板字符串”。

Firefox 34、Chrome 41 和 Edge 12 及更高版本支持模板文本,但 Internet Explorer 不支持。

模板文本可用于表示多行字符串,并可以使用“插值”来插入变量:

var a = 123, str = `---
   a is: ${a}
---`;
console.log(str);

输出:

---
   a is: 123
---

更重要的是,它们不仅可以包含变量名称,还可以包含任何JavaScript表达式:

var a = 3, b = 3.1415;

console.log(`PI is nearly ${Math.max(a, b)}`);

答案 2

ECMAScript 6 提出了一种新型的字符串文本,使用反引号作为分隔符。这些文本允许嵌入基本的字符串插值表达式,然后自动分析和计算这些表达式。

let person = {name: 'RajiniKanth', age: 68, greeting: 'Thalaivaaaa!' };

let usualHtmlStr = "<p>My name is " + person.name + ",</p>\n" +
  "<p>I am " + person.age + " old</p>\n" +
  "<strong>\"" + person.greeting + "\" is what I usually say</strong>";

let newHtmlStr =
 `<p>My name is ${person.name},</p>
  <p>I am ${person.age} old</p>
  <p>"${person.greeting}" is what I usually say</strong>`;

console.log(usualHtmlStr);
console.log(newHtmlStr);

如您所见,我们使用了一系列字符,这些字符被解释为字符串文本,但该形式的任何表达式都会立即以内联方式进行解析和计算。`${..}

插值字符串文本的一个非常好的好处是允许它们跨多行拆分:

var Actor = {"name": "RajiniKanth"};

var text =
`Now is the time for all good men like ${Actor.name}
to come to the aid of their
country!`;
console.log(text);
// Now is the time for all good men like RajiniKanth
// to come to the aid of their
// country!

插值表达式

任何有效的表达式都允许出现在内插字符串文本中,包括函数调用,内联函数表达式调用,甚至其他内插字符串文本!${..}

function upper(s) {
  return s.toUpperCase();
}
var who = "reader"
var text =
`A very ${upper("warm")} welcome
to all of you ${upper(`${who}s`)}!`;
console.log(text);
// A very WARM welcome
// to all of you READERS!

在这里,内部插值字符串文字在将变量与字符串组合时对我们来说更加方便,而不是。此外,为了保持注释,内插字符串文本只是在它出现的地方进行词法作用域,而不是以任何方式动态作用域:`${who}s`who"s"who + "s"

function foo(str) {
  var name = "foo";
  console.log(str);
}
function bar() {
  var name = "bar";
  foo(`Hello from ${name}!`);
}
var name = "global";
bar(); // "Hello from bar!"

通过减少烦恼,将模板文本用于HTML绝对更具可读性。

简单的旧方法:

'<div class="' + className + '">' +
  '<p>' + content + '</p>' +
  '<a href="' + link + '">Let\'s go</a>'
'</div>';

使用 ECMAScript 6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • 字符串可以跨多行。
  • 您不必转义引号字符。
  • 您可以避免使用类似“>”的分组
  • 您不必使用加号运算符。

标记的模板文本

我们还可以标记模板字符串,当模板字符串被标记时,文本和替换被传递给函数,该函数返回结果值。

function myTaggedLiteral(strings) {
  console.log(strings);
}

myTaggedLiteral`test`; //["test"]

function myTaggedLiteral(strings, value, value2) {
  console.log(strings, value, value2);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

我们可以在这里使用点差运算符来传递多个值。第一个参数(我们称之为字符串)是所有纯字符串(任何内插表达式之间的内容)的数组。

然后,我们使用 将所有后续参数收集到一个名为 values 的数组中,尽管您当然可以将它们作为字符串参数后面的单个命名参数,就像我们上面所做的那样(,等)。... gather/rest operatorvalue1value2

function myTaggedLiteral(strings, ...values) {
  console.log(strings);
  console.log(values);
}

let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

收集到值数组中的参数是在字符串文本中找到的已计算插值表达式的结果。标记的字符串文本类似于在计算插值之后但在编译最终字符串值之前执行的处理步骤,这样可以更好地控制从文本生成字符串。让我们看一个创建可重用模板的示例。

const Actor = {
  name: "RajiniKanth",
  store: "Landmark"
}

const ActorTemplate = templater`<article>
  <h3>${'name'} is a Actor</h3>
  <p>You can find his movies at ${'store'}.</p>

</article>`;

function templater(strings, ...keys) {
  return function(data) {
    let temp = strings.slice();
    keys.forEach((key, i) => {
      temp[i] = temp[i] + data[key];
    });
    return temp.join('');
  }
};

const myTemplate = ActorTemplate(Actor);
console.log(myTemplate);

原始字符串

我们的标签函数接收我们称之为字符串的第一个参数,这是一个数组。但还有一个额外的数据位:所有字符串的原始未处理版本。您可以使用该属性访问这些原始字符串值,如下所示:.raw

function showraw(strings, ...values) {
  console.log(strings);
  console.log(strings.raw);
}
showraw`Hello\nWorld`;

如您所见,字符串的原始版本保留了转义序列,而字符串的处理版本将其视为未转义的真正新行。ECMAScript 6 附带了一个内置函数,可用作字符串文本标记:。它只是通过字符串的原始版本:\nString.raw(..)

console.log(`Hello\nWorld`);
/* "Hello
World" */

console.log(String.raw`Hello\nWorld`);
// "Hello\nWorld"