JavaScript 中反引号 (`) 的用法

IT技术 javascript backticks single-quotes template-strings backquote
2021-01-29 09:47:04

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

var s = `abc`;

反引号的行为实际上与单引号的行为不同吗?


† 请注意,在程序员中,“反引号”是更普遍称为重音符号的名称之一程序员有时也使用替代名称“反引号”和“背刻”。此外,在 Stack Overflow和其他地方,“反引号”的其他常见拼写是“反引号”和“反引号”。

6个回答

这是一个称为模板文字的功能

在 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)}`);
鉴于缺乏对它的支持,是否有任何可行的 polyfils?
2021-03-10 09:47:04
@AlexanderDixon,没有你不能在传统意义上的填充工具这种语言特性,虽然你可能会使用模板下划线lodash组合的变量字符串与multilining使用数组的字符串:["a", "b"].join(""); // both string elements written in new lines但除此之外,可能会使用像Babel这样的“转译器”将 ES6+ 转换为 ES5
2021-03-14 09:47:04
@UnionP 包括 MS Edge 在内的所有主流浏览器都支持:kangax.github.io/compat-table/es6/#test-template_literals
2021-03-28 09:47:04
使用反引号标记模板文字这是有效的,并且效果很好:alert`1`
2021-04-04 09:47:04
@kiki 看起来脚本语言是 ECMAScript 的变体。Google App 脚本显然不支持 ECMAScript 2015 功能。我无法找到他们使用的语言的官方规范。
2021-04-09 09:47:04

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

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

然后,我们收集了所有后续参数为使用数组叫做值... gather/rest operator,虽然你当然可以留下他们作为以下参数就像我们上面那样的字符串(个人命名的参数value1value2等等)。

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

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

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

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`;

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

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

console.log(String.raw`Hello\nWorld`);
// "Hello\nWorld"
向下滚动查看作者的帐户,没有失望!很好的解释。xD
2021-03-10 09:47:04
包含“是一个内插字符串文字只是词法范围”的句子是不可理解的。你能修好它吗?
2021-03-19 09:47:04
很好的解释和广泛的覆盖面,谢谢。只是想补充一点,Mozilla 开发人员站点模板文字(模板字符串)也有一个很好的概述,其中涵盖了一些额外的方面。
2021-03-21 09:47:04
很好的答案!小评论,在您的标记模板文字部分,我相信两个示例数组输出myTaggedLiteral`test ${someText} ${2 + 3}`;应该是//["test ", " "](即未修剪的字符串)。
2021-03-25 09:47:04
Nit:“ECMAScript 6 提出了一种新类型的字符串文字”这不是字符串文字,而是模板文字。如果它没有标记,则在评估时会产生一个字符串。这不仅仅是教条式的,在某些地方您可以使用字符串文字,但不允许使用模板文字(例如未计算的参数名称、module标识符...)。
2021-04-02 09:47:04

反引号 ( `) 用于定义模板文字。模板字面量是 ECMAScript 6 中的一项新功能,可以更轻松地处理字符串。

特征:

  • 我们可以在模板文字中插入任何类型的表达式。
  • 它们可以是多行的。

注意:我们可以轻松地在反引号 ( ) 中使用单引号 ( ') 和双"引号 ( `)。

例子:

var nameStr = `I'm "Alpha" Beta`;

为了插入变量或表达式,我们可以使用${expression}符号。

var name = 'Alpha Beta';
var text = `My name is ${name}`;
console.log(text); // My name is Alpha Beta

多行字符串意味着您不再需要使用\n新行。

例子:

const name = 'Alpha';
console.log(`Hello ${name}!
How are you?`);

输出:

Hello Alpha!
How are you?

除了字符串插值,您还可以使用反引号调用函数。


var sayHello = function () {
    console.log('Hello', arguments);
}

// To call this function using ``

sayHello`some args`; // Check console for the output

// Or
sayHello`
    some args
`;

检查样式组件他们大量使用它。

反引号包含模板文字,以前称为模板字符串。模板文字是允许嵌入表达式和字符串插值功能的字符串文字。

模板文字在占位符中嵌入了表达式,由美元符号和表达式周围的大括号表示,即${expression}. 占位符/表达式被传递给一个函数。默认函数只是连接字符串。

要转义反引号,请在它前面放一个反斜杠:

`\`` === '`'; => true

使用反引号可以更轻松地编写多行字符串:

console.log(`string text line 1
string text line 2`);

或者

console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);

与普通 JavaScript:

console.log('string text line 1\n' +
'string text line 2');

或者

console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');

转义序列:

  • \u例如,由 开始的 Unicode 转义\u00A9
  • \u{}例如,由 指示的 Unicode 代码点转义\u{2F804}
  • \x例如,由 开始的十六进制转义\xA9
  • \例如,以和 (a) 数字开头的八进制文字转义\251