Uso del carácter de retroceso (`) en JavaScript

277

En JavaScript, un backtick parece funcionar igual que una cita simple. Por ejemplo, puedo usar un backtick para definir una cadena como esta:

var s = `abc`;

¿Hay alguna forma en que el comportamiento del backtick realmente difiere del de una cita simple?


† Tenga en cuenta que entre los programadores, "backtick" es un nombre para lo que generalmente se llama acento grave . Los programadores también usan a veces los nombres alternativos "backquote" y "backgrave". Además, en Stack Overflow y en otros lugares, otras ortografías comunes para "backtick" son "back-tick" y "back tick".

vancewang
fuente
Lea a continuación también el uso de plantillas etiquetadas. Este es un uso diferente a la pregunta que se hace. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Y esto se explica en una de las respuestas más largas a continuación. stackoverflow.com/a/40062505/3281336
PatS el
1
"Backgrave" es ridículo, porque no hay acento grave hacia adelante - eso se llama acento agudo
Walter Tross

Respuestas:

298

Esta es una característica llamada plantilla de literales .

Se llamaron "cadenas de plantillas" en ediciones anteriores de la especificación ECMAScript 2015.

Los literales de plantilla son compatibles con Firefox 34, Chrome 41 y Edge 12 y superior, pero no con Internet Explorer.

Los literales de plantilla se pueden usar para representar cadenas de varias líneas y pueden usar "interpolación" para insertar variables:

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

Salida:

---
   a is: 123
---

Lo que es más importante, pueden contener no solo un nombre de variable, sino cualquier expresión de JavaScript:

var a = 3, b = 3.1415;

console.log(`PI is nearly ${Math.max(a, b)}`);
try-catch-finally
fuente
2
¿Hay algún polyfils viable para esto dada la falta de soporte para ello?
Alexander Dixon
3
@AlexanderDixon, no, no puede polyfill esta característica del lenguaje en el sentido clásico, aunque es posible utilizar plantillas de subrayado o lodash para las variables en las cadenas en combinación con multilining cadenas utilizando matrices: ["a", "b"].join(""); // both string elements written in new lines. Pero aparte de esto uno podría utilizar un "transpiler" como Babel para convertir ES6 + para ES5
try-catch-finally
2
¡Etiquetado de literales de plantilla usando backticks! Esto es válido y funciona bien:alert`1`.
Константин Ван
@UnionP Compatible con todos los principales navegadores, incluido MS Edge: kangax.github.io/compat-table/es6/#test-template_literals
Jonathan Cross
2
@kiki parece que el lenguaje del script es una variante de ECMAScript. Los scripts de la aplicación Google no son compatibles con las características de ECMAScript 2015, obviamente. No pude encontrar una especificación oficial de qué idioma están usando.
try-catch-finally
162

ECMAScript 6 viene con un nuevo tipo de cadena literal, usando el backtick como delimitador. Estos literales permiten incrustar expresiones básicas de interpolación de cadenas, que luego se analizan y evalúan automáticamente.

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

Como puede ver, utilizamos `alrededor de una serie de caracteres, que se interpretan como un literal de cadena, pero cualquier expresión del formulario ${..}se analiza y evalúa en línea de inmediato.

Un beneficio realmente agradable de los literales de cadena interpolados es que se les permite dividirse en varias líneas:

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!

Expresiones Interpoladas

¡Cualquier expresión válida puede aparecer dentro ${..}de un literal de cadena interpolado, incluidas las llamadas a funciones, las llamadas a expresiones de función en línea e incluso otros literales de cadena interpolados!

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!

Aquí, el `${who}s`literal de cadena interpolado interno fue un poco más conveniente para nosotros al combinar la whovariable con la "s"cadena, en lugar de who + "s". Además, para mantener una nota, un literal de cadena interpolado solo tiene un alcance léxico donde aparece, no tiene un alcance dinámico de ninguna manera:

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

Usar el literal de plantilla para el HTML es definitivamente más legible al reducir la molestia.

La vieja manera simple:

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

Con ECMAScript 6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • Su cadena puede abarcar varias líneas.
  • No tiene que escapar de los caracteres de cita.
  • Puede evitar agrupaciones como: '">'
  • No tiene que usar el operador más.

Etiquetado Literales de plantilla

También podemos etiquetar una cadena de plantilla, cuando se etiqueta una cadena de plantilla, los literales y las sustituciones se pasan a la función que devuelve el valor resultante.

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

Podemos usar el operador de propagación aquí para pasar múltiples valores. El primer argumento, lo llamamos cadenas, es una matriz de todas las cadenas simples (el material entre cualquier expresión interpolada).

A continuación, recogemos todos los argumentos posteriores en una matriz llamada valores utilizando el ... gather/rest operator, aunque se puede, por supuesto, ellos han dejado como parámetros con nombre individuales siguiendo las cadenas de parámetros como lo hicimos anteriormente ( value1, value2, etc.).

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

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

Los argumentos reunidos en nuestra matriz de valores son los resultados de las expresiones de interpolación ya evaluadas que se encuentran en el literal de cadena. Un literal de cadena etiquetado es como un paso de procesamiento después de evaluar las interpolaciones, pero antes de que se compile el valor final de la cadena, lo que le permite un mayor control sobre la generación de la cadena a partir del literal. Veamos un ejemplo de creación de plantillas reutilizables.

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

Cuerdas crudas

Nuestras funciones de etiqueta reciben un primer argumento que llamamos cadenas, que es una matriz. Pero hay un bit adicional de datos incluidos: las versiones sin procesar sin procesar de todas las cadenas. Puede acceder a esos valores de cadena sin formato utilizando la .rawpropiedad, como esta:

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

Como puede ver, la versión sin procesar de la cadena conserva la \nsecuencia escapada , mientras que la versión procesada de la cadena la trata como una nueva línea real sin escape. ECMAScript 6 viene con una función incorporada que puede ser usado como una etiqueta literal de cadena: String.raw(..). Simplemente pasa por las versiones en bruto de las cadenas:

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

console.log(String.raw`Hello\nWorld`);
// "Hello\nWorld"
Thalaivar
fuente
1
¡Gran respuesta! Comentario menor, en su sección de Literales de plantilla etiquetada, creo que las dos salidas de matriz de ejemplo para myTaggedLiteral`test ${someText} ${2 + 3}`;deberían ser //["test ", " "](es decir, no cadenas recortadas).
Michael Krebs
3
Desplácese hacia abajo para ver la cuenta del autor, no estaba decepcionado! Buena explicación. xD
varun
Buena explicación y amplia cobertura, gracias. Solo quería agregar que también hay una buena descripción del sitio para desarrolladores de Mozilla Literales de plantilla (cadenas de plantilla) que cubre algunos aspectos adicionales.
Dev Ops
1
Nit: "ECMAScript 6 viene con un nuevo tipo de cadena literal" No es una cadena literal, es una plantilla literal. Resulta en una cadena cuando se evalúa si no está etiquetada. Esto no es solo dogmático, hay lugares donde puede usar literales de cadena donde los literales de plantilla no están permitidos (como nombres de parámetros no computados, identificadores de módulos ...).
TJ Crowder
La oración que incluye "es un literal de cadena interpolado tiene un alcance léxico" es incomprensible. ¿Puedes arreglarlo?
Peter Mortensen
21

Backticks ( `) se utilizan para definir literales de plantilla. Los literales de plantilla son una nueva característica en ECMAScript 6 para facilitar el trabajo con cadenas.

caracteristicas:

  • podemos interpolar cualquier tipo de expresión en los literales de plantilla.
  • Pueden ser multilínea.

Nota: podemos usar comillas simples ( ') y comillas dobles ( ") dentro de los backticks ( `).

Ejemplo:

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

Para interpolar las variables o la expresión, podemos usar la ${expression}notación para eso.

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

Las cadenas de varias líneas significan que ya no tiene que usarlas \npara nuevas líneas.

Ejemplo:

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

Salida:

Hello Rohit!
How are you?
Rohit Jindal
fuente
15

Los backticks encierran literales de plantilla, anteriormente conocidos como cadenas de plantilla. Los literales de plantilla son literales de cadena que permiten expresiones incrustadas y características de interpolación de cadena.

Los literales de plantilla tienen expresiones incrustadas en marcadores de posición, denotados por el signo de dólar y corchetes alrededor de una expresión, es decir ${expression}. El marcador de posición / expresiones se pasan a una función. La función predeterminada simplemente concatena la cadena.

Para escapar de un backtick, coloque una barra diagonal inversa antes:

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

Use las teclas de retroceso para escribir más fácilmente una cadena de varias líneas:

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

o

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

vs JavaScript vainilla:

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

o

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

Secuencias de escape:

  • Escapes Unicode iniciados por \u, por ejemplo\u00A9
  • Escapes de puntos de código Unicode indicados por \u{}, por ejemplo\u{2F804}
  • Escapes hexadecimales iniciados por \x, por ejemplo\xA9
  • Escapes literales octales iniciados por \y (a) dígitos, por ejemplo\251
mrmaclean89
fuente
10

Resumen:

Backticks en JavaScript es una característica que se introduce en ECMAScript 6 // ECMAScript 2015 para crear cadenas dinámicas fáciles. Esta característica ECMAScript 6 también se denomina literal de cadena de plantilla . Ofrece las siguientes ventajas en comparación con las cadenas normales:

  • En las cadenas de plantilla se permiten los saltos de línea y, por lo tanto, pueden ser multilínea. Los literales de cadena normales (declarados con ''o "") no pueden tener saltos de línea.
  • Podemos interpolar fácilmente valores variables a la cadena con la ${myVariable}sintaxis.

Ejemplo:

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

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

console.log(story);

Compatibilidad del navegador:

El literal de cadena de plantilla es compatible de forma nativa con todos los principales proveedores de navegadores (excepto Internet Explorer). Por lo tanto, es bastante seguro de usar en su código de producción. Puede encontrar una lista más detallada de las compatibilidades del navegador aquí .

Willem van der Veen
fuente
10

Además de la interpolación de cadenas, también puede llamar a una función utilizando el retroceso.


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

// To call this function using ``

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

// Or
sayHello`
    some args
`;

Verifique el componente con estilo . Lo usan mucho.

Ankit Kumar
fuente
7

Lo bueno es que podemos hacer matemáticas básicas directamente:

let nuts = 7

more.innerHTML = `

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

<hr>

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

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

Se volvió realmente útil en una función de fábrica:

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>

NVRM
fuente
3
nadie más se rió cmon ahora
StayCool 03 de