JavaScript中反引号字符(`)的用法


276

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

var s = `abc`;

有没有一种方法可以使反引号的行为实际上不同于单引号的行为?


†请注意,在程序员中,“反勾号”是通常被称为重音符号的一个名称。程序员有时还会使用备用名称 “ backquote”和“ backgrave”。同样,在Stack Overflow和其他地方,“ backtick”的其他常见拼写是“ back-tick”和“ back tick”。


请同时阅读以下有关标记模板的用法。这与询问的问题有不同的用途。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference / ... 这在下面的较长答案之一中进行了解释。 stackoverflow.com/a/40062505/3281336
PatS

1
“backgrave”是荒谬的,因为没有前锋重音-这就是所谓的重音符
瓦尔特Tross

Answers:


296

这是称为模板文字的功能。

在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
鉴于缺乏支持,是否有可行的polyfils?
亚历山大·迪克森

3
@AlexanderDixon,没有你不能在传统意义上的填充工具这种语言特性,虽然你可能会使用模板下划线lodash组合的变量字符串与multilining使用数组的字符串:["a", "b"].join(""); // both string elements written in new lines。但是除此之外,还可以使用Babel这样的“编译器” 将ES6 +转换为ES5
最终尝试

2
使用反引号标记模板文字!这是有效的,并且效果很好:alert`1`
КонстантинВан

@UnionP受包括MS Edge在内的所有主要浏览器的支持:kangax.github.io/compat-table/es6/#test-template_literals
Jonathan Cross

2
@kiki似乎脚本语言是ECMAScript的变体。Google App脚本显然不支持ECMAScript 2015功能。我找不到官方规范,说明他们使用的是哪种语言。
最终

162

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
// 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"

1
好答案!小注释,在“标记的模板文字”部分中,我认为myTaggedLiteral`test ${someText} ${2 + 3}`;应该为两个示例数组输出//["test ", " "](即未修剪的字符串)。
Michael Krebs'2

3
向下滚动以查看作者的叙述,并不感到失望!很好的解释。xD
varun

很好的解释和广泛的报道,谢谢。只是想补充一下,Mozilla开发人员网站上的模板文字(模板字符串)也有很好的概述,其中涵盖了一些其他方面。
Dev Ops

1
Nit:“ ECMAScript 6提供了一种新型的字符串文字”它不是字符串文字,它是模板文字。如果未加标签,则结果为字符串。这不仅是教条主义,在某些地方可以使用不允许使用模板文字的字符串文字(例如,未计算的参数名称,模块标识符...)。
TJ Crowder

包含“是插值字符串文字只是词法作用域”的句子是无法理解的。你能修好它吗?
Peter Mortensen

21

反引号(`)用于定义模板文字。模板文字是ECMAScript 6中的一项新功能,可简化字符串的使用。

特征:

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

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

例:

var nameStr = `I'm "Rohit" Jindal`;

要对变量或表达式进行插值,可以为此使用${expression}符号。

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

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

例:

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

输出:

Hello Rohit!
How are you?

15

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

模板文字具有嵌入在占位符中的表达式,用美元符号和表达式(即)周围的大括号表示${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) + '.');

转义序列:

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

10

摘要:

JavaScript中的反引号是ECMAScript 6 // ECMAScript 2015中引入的一项功能,用于创建简单的动态字符串。此ECMAScript 6功能也称为模板字符串文字。与普通字符串相比,它具有以下优点:

  • 在模板字符串中允许换行,因此可以是多行。普通字符串文字(用''或声明"")不允许换行。
  • 我们可以使用${myVariable}语法轻松地将变量值插入到字符串中。

例:

const name = 'Willem';
const age = 26;

const story = `
  My name is: ${name}
  And I'm: ${age} years old
`;

console.log(story);

浏览器兼容性:

所有主要浏览器供应商(Internet Explorer除外)都固有地支持模板字符串文字。因此,在生产代码中使用它非常节省。浏览器兼容性的更详细列表可以在此处找到。


10

除字符串插值外,您还可以使用反勾号来调用函数。


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

// To call this function using ``

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

// Or
sayHello`
    some args
`;

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


7

好消息是我们可以直接进行基本数学运算:

let nuts = 7

more.innerHTML = `

<h2>You collected ${nuts} nuts so far!

<hr>

Double it, get ${nuts + nuts} nuts!!

`
<div id="more"></div>

它在工厂功能中变得非常有用:

function nuts(it){
  return `
    You have ${it} nuts! <br>
    Cosinus of your nuts: ${Math.cos(it)} <br>
    Triple nuts: ${3 * it} <br>
    Your nuts encoded in BASE64:<br> ${btoa(it)}
  `
}

nut.oninput = (function(){
  out.innerHTML = nuts(nut.value)
})
<h3>NUTS CALCULATOR
<input type="number" id="nut">

<div id="out"></div>


3
现在没有其他人笑过吗
StayCool
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.