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

时间:2014-12-28 15:59:46

标签: javascript backticks single-quotes template-strings backquote

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

var s = `abc`;

有什么方法可以使反引号的行为与单引号的行为有所不同?


†请注意,在程序员中,"反击"是一般称为grave accent的名称。程序员有时也会使用alternate names"反引号"和" backgrave"。此外,on Stack Overflow和其他地方,"反击"的其他常见拼写。是"反击"和"返回"。

10 个答案:

答案 0 :(得分:224)

这是一项名为template literals的功能。

在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)}`);

答案 1 :(得分:116)

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>`
  • 您的字符串可以跨越多行。
  • 您不必转义引号字符。
  • 您可以避免分组,例如:'“&gt;'
  • 您不必使用加号运算符。

标记模板文字

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

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

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

然后我们使用... gather/rest operator将所有后续参数收集到一个名为values的数组中,尽管你可以将它们作为单独的命名参数留在strings参数之后,就像我们在上面(value1, value2, etc.)所做的那样。 / p>

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 Strings

我们的标记函数接收第一个参数,我们称之为字符串,它是一个数组。但是还有一些数据包括:所有字符串的原始未处理版本。您可以使用.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"

答案 2 :(得分:19)

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

功能

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

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

示例:

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?

答案 3 :(得分:11)

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

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

要逃避反击,请在其前面加一个反斜杠:

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

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

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

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

VS。 vanilla 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

答案 4 :(得分:3)

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


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

// to call this function using ``

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

// or
sayHello`
    some args
`;

Check styled component,他们大量使用它。

答案 5 :(得分:2)

摘要:

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除外)都原生支持模板字符串文字。因此,在生产代码中使用它非常节省。 here可以找到浏览器兼容性的详细列表。

答案 6 :(得分:1)

好的部分是我们可以直接进行基础数学运算

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>

答案 7 :(得分:0)

这是一个非常有用的功能,例如,这里是一个Node.js代码片段,用于测试3秒计时功能的设置。

const waitTime = 3000;
console.log(`setting a ${waitTime/1000} second delay`);

说明

  1. 将等待时间声明为3000
  2. 使用反引号可以将“等待时间”除以1000的计算结果嵌入到所选文本的同一行中。
  3. 进一步使用'waitTime'常量调用计时器函数将导致3秒钟的延迟,这在console.log参数中计算得出。

答案 8 :(得分:0)

您也可以制作模板模板,并访问私有变量。

var a= {e:10, gy:'sfdsad'}; //global object

console.log(`e is ${a.e} and gy is ${a.gy}`); 
//e is 10 and gy is sfdsad

var b = "e is ${a.e} and gy is ${a.gy}" // template string
console.log( `${b}` );
//e is ${a.e} and gy is ${a.gy}

console.log( eval(`\`${b}\``) ); // convert template string to template
//e is 10 and gy is sfdsad

backtick( b );   // use fonction's variable
//e is 20 and gy is fghj

function backtick( temp ) {
  var a= {e:20, gy:'fghj'}; // local object
  console.log( eval(`\`${temp}\``) );
}

答案 9 :(得分:0)

很多评论回答了您的大多数问题,但我主要想为这个问题做贡献:

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

我注意到模板字符串的区别是无法将其设置为对象属性。 this post中的更多信息;接受的答案中的一个有趣的报价:

模板字符串是表达式,而不是literals1。

但是,基本上,如果您想将其用作对象属性,则必须使用方括号将其包装。

// Throws error
const object = {`templateString`: true};

// Works
const object = {[`templateString`]: true};