Un camino para comprender los literales de plantillas en JavaScript

La especificación ECMAScript de 2015 ( ES6 ) agregó una nueva característica a JavaScript: los literales de plantilla. Los literales de plantilla nos brindan un nuevo mecanismo para crear valores de cadena... Este mecanismo tiene muchas características poderosas, como facilitar la creación de construcciones de varias líneas y usar marcadores de posición para incrustar resultados de expresión en cadenas. Además, existe otra posibilidad aquí: literales de plantilla etiquetados. Esta es una forma extendida de literales de plantilla. Las plantillas de etiquetas le permiten crear cadenas usando expresiones dentro de cadenas y usando funciones especiales. Todo esto amplía la capacidad de los programadores para trabajar con cadenas, lo que permite, por ejemplo, crear cadenas dinámicas que pueden ser URL , o escribir funciones para ajustar elementos HTML .







En este artículo, aprenderá las diferencias entre los valores de cadena regulares, especificados con comillas simples o dobles, y los literales de plantilla. Aprenderá sobre diferentes formas de declarar cadenas con diferentes características, incluidas cadenas multilínea y cadenas dinámicas que cambian según el valor de una variable o expresión. Aprenderá a trabajar con plantillas de etiquetas y verá ejemplos reales de su uso.



Declarar cadenas



En esta sección, recordamos cómo se declaran las cadenas usando comillas simples o dobles, y luego echamos un vistazo a cómo se hace lo mismo cuando se usan literales de plantilla.



Una cadena de JavaScript se puede considerar como una secuencia de caracteres entre comillas simples ( ' '):



const single = 'Every day is a good day when you paint.'


Otra forma de declarar cadenas es usar comillas dobles ( " "):



const double = "Be so very light. Be a gentle whisper."


En JavaScript, no existen grandes diferencias entre dichas cadenas. En otros idiomas, el uso de diferentes comillas al declarar cadenas puede significar, por ejemplo, que las cadenas de un tipo se pueden interpolar y otras no. Aquí entendemos por "interpolación" la capacidad de calcular los valores de las expresiones de marcador de posición que desempeñan el papel de porciones dinámicas de cadenas y participan en la formación de los valores de cadena resultantes.



Qué cadenas usar cuando se declaran con comillas simples o dobles es en gran medida una cuestión de preferencia personal y convenciones de codificación. Sin embargo, si aparece el mismo tipo de comillas en una cadena delimitada por uno de estos tipos de comillas, se deben omitir . Las citas de un tipo diferente en tales cadenas no necesitan escaparse.



//     ,   
const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross'

//     ,   
const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross"

console.log(single);
console.log(double);


Llamar a un par de métodos log()resultará en el envío de dos líneas idénticas a la consola .



"We don't make mistakes. We just have happy accidents." - Bob Ross
"We don't make mistakes. We just have happy accidents." - Bob Ross


Los literales de plantilla, por otro lado, se declaran usando comillas invertidas ( ` `):



const template = `Find freedom on this canvas.`


No es necesario escapar de las comillas simples o dobles aquí:



const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross


Pero las comillas inversas en tales cadenas deben evitarse:



const template = `Template literals use the \` character.`


Los literales de plantilla tienen todas las capacidades de las cadenas normales. Por lo tanto, probablemente pueda reemplazar todas las cadenas de su proyecto con literales de plantilla sin perder nada. Sin embargo, las convenciones de codificación más comunes especifican que los literales de plantilla solo deben usarse cuando se necesitan sus capacidades especiales. Las cadenas ordinarias siempre se declaran utilizando comillas simples o dobles para mantener la coherencia del código. El código base del proyecto, al escribir que sigue este estándar, será más fácil de leer para los desarrolladores que no estén familiarizados con él previamente.



Ahora que hemos hablado de declarar cadenas usando comillas simples, comillas dobles y comillas inversas, podemos pasar a la primera fortaleza de los literales de plantilla. Es decir, a la posibilidad de describir cadenas de varias líneas.



Cuerdas multilínea



En esta sección, primero hablaremos sobre cómo se declararon las cadenas de varias líneas antes de ES6, y luego veremos cómo las plantillas literales simplifican esta tarea.



Inicialmente, si tenía que ingresar una variable de cadena que constaba de varias líneas en un editor de texto, se usaba el operador de concatenación de cadenas . El siguiente ejemplo de concatenación de cadenas ilustra esta idea:



const address =
  'Homer J. Simpson' +
  '742 Evergreen Terrace' +
  'Springfield'


Este enfoque puede permitirle dividir líneas largas en trozos pequeños y organizarlas en un editor de texto en varias líneas. Pero esto no afecta de ninguna manera cómo resultará la última fila. En este caso, el valor de la constante de cadena se ubicará en una línea. Las partes de las que se ensambla el valor de la cadena no estarán separadas por saltos de línea o espacios. Si imprime una constante en la consola address, aparecerá lo siguiente:



Homer J. Simpson742 Evergreen TerraceSpringfield


Otro enfoque para escribir tales líneas en editores de código es usar el carácter de barra invertida ( \), que se coloca al final de los fragmentos de línea, y después del cual, en una nueva línea, se ubican los nuevos fragmentos:



const address =
  'Homer J. Simpson\
  742 Evergreen Terrace\
  Springfield'


Este enfoque conserva, por ejemplo, los espacios antes de los fragmentos de línea, pero el valor de la variable, si se imprime en la consola, estará nuevamente representado por una sola línea:



Homer J. Simpson  742 Evergreen Terrace  Springfield


Puede crear una cadena multilínea real usando el carácter de salto de línea ( \n):



const address =
  'Homer J. Simpson\n' +
  '742 Evergreen Terrace\n' +
  'Springfield'


Al mostrar un valor de cadena almacenado en la consola address, este valor abarcará varias líneas:



Homer J. Simpson
742 Evergreen Terrace
Springfield


Sin embargo, usar el carácter de nueva línea para crear cadenas de varias líneas no es particularmente conveniente y fácil. Por otro lado, crear cadenas de varias líneas utilizando literales de plantilla es mucho más fácil y conveniente. No es necesario concatenar cadenas, no es necesario utilizar una nueva línea o una barra invertida. Para crear cadenas de varias líneas usando literales de plantilla, es bastante simple, al final del siguiente fragmento de una línea, presione la tecla Entery continúe ingresando la siguiente línea del literal de plantilla:



const address = `Homer J. Simpson
742 Evergreen Terrace
Springfield`


Si envía esta constante a la consola, el texto se verá igual que en el editor:



Homer J. Simpson
742 Evergreen Terrace
Springfield


Aquí debe tenerse en cuenta que si hay espacios entre las comillas invertidas utilizadas para alinear el código, estos espacios se incluirán en el literal de plantilla resultante. Considere el siguiente ejemplo:



const address = `Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield`


Aunque este estilo de codificación hace que sea más fácil de leer, lo que llega a la consola después de enviarlo no se verá muy atractivo:



Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield


Ahora, habiendo tratado con cadenas de varias líneas, hablemos de cómo puede incrustar los resultados de la evaluación de varias expresiones en cadenas declaradas de diferentes maneras, es decir, hablemos de interpolar expresiones.



Expresiones de interpolación



Anteriormente, antes de ES6, la concatenación se usaba para crear cadenas dinámicas formadas por valores de variable o expresión:



const method = 'concatenation'
const dynamicString = 'This string is using ' + method + '.'


Si envía dynamicStringa la consola, obtiene lo siguiente:



This string is using concatenation.


Cuando se utilizan literales de plantilla, las expresiones se pueden incrustar en la cadena mediante marcadores de posición. Un marcador de posición es una construcción de vista ${}. En este caso, todo lo contenido entre llaves se considera código JavaScript, y todo lo que está fuera de esta construcción se considera una cadena:



const method = 'interpolation'
const dynamicString = `This string is using ${method}.`


Al enviar dynamicStringa la consola, obtiene el siguiente resultado:



This string is using interpolation.


Un ejemplo común de incrustación de valores en cadenas es la creación de URL dinámicas. El uso de la concatenación para este propósito conduce a la aparición de construcciones engorrosas e inconvenientes. Por ejemplo, aquí hay una función que genera una cadena de acceso OAuth :



function createOAuthString(host, clientId, scope) {
  return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope
}

createOAuthString('https://github.com', 'abc123', 'repo,user')


Si imprime el resultado de esta función en la consola, obtiene lo siguiente:



https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user


Cuando se utiliza la interpolación, los programadores ya no necesitan tener cuidado con las comillas que delimitan partes de la cadena y dónde se encuentra exactamente el operador de concatenación. Este es el mismo ejemplo, reescrito utilizando literales de plantilla:



function createOAuthString(host, clientId, scope) {
  return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
}

createOAuthString('https://github.com', 'abc123', 'repo,user')


El resultado de la función será el siguiente:



https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user


Puede utilizar el método trim () para eliminar los espacios en blanco iniciales y finales de una cadena creada con una plantilla literal . Por ejemplo, en el siguiente fragmento de código para crear un elemento HTMLcon una referencia personalizada, se utiliza una función de flecha :



const menuItem = (url, link) =>
  `
<li>
  <a href="${url}">${link}</a>
</li>
`.trim()

menuItem('https://google.com', 'Google')


Los espacios iniciales y finales se eliminarán de la línea final para garantizar que el elemento se represente correctamente:



<li>
  <a href="https://google.com">Google</a>
</li>


Se pueden interpolar expresiones completas, no solo variables. Por ejemplo, como aquí, donde el resultado de sumar dos números está incrustado en una cadena:



const sum = (x, y) => x + y
const x = 5
const y = 100
const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`

console.log(string)


Aquí se declaran la función sum()y las constantes xy y. Después de eso, la línea usa tanto la función como estas constantes. Así es como se ve la constante stringcuando se imprime en la consola:



The sum of 5 and 100 is 105.


Este mecanismo puede ser especialmente útil cuando se usa el operador ternario , que le permite verificar las condiciones al formar una cadena:



const age = 19
const message = `You can ${age < 21 ? 'not' : ''} view this page`
console.log(message)


La constante messageimpresa en la consola puede cambiar, según sea mayor o menor que 21, el valor almacenado en age. Dado que este valor es 19 en nuestro ejemplo, se enviará lo siguiente a la consola:



You can not view this page


Ahora sabe cómo puede beneficiarse de la interpolación de expresiones cuando se utilizan literales de plantilla. En la siguiente sección, daremos un paso más y exploraremos los patrones de etiquetado y hablaremos sobre cómo trabajar con expresiones pasadas en ámbitos que coinciden con marcadores de posición.



Plantillas de etiquetas



Las plantillas de etiquetas son una forma extendida de literales de plantilla. Las plantillas etiquetadas comienzan con una función etiquetada que analiza el literal de la plantilla, lo que le da al desarrollador más control sobre el proceso de generación de cadenas dinámicas.



En el siguiente ejemplo, creamos una función tagque planeamos usar en el rol de una función con la que se realizan operaciones en una plantilla de etiqueta. El primer parámetro con nombre para esta función stringses una matriz de cadenas literales. Las expresiones en línea se colocan en el segundo parámetro utilizando la sintaxis de los parámetros restantes . Para ver el contenido de estos parámetros, se pueden visualizar en la consola:



function tag(strings, ...expressions) {
  console.log(strings)
  console.log(expressions)
}


Si usa una función al crear una plantilla de etiqueta tag, puede obtener la siguiente construcción:



const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`


Dado que la función tagrealiza salida a la consola stringsy expressions, al ejecutar este código, se enviará lo siguiente a la consola:



["This is a string with ", " and ", " and ", " interpolated inside."]
[true, false, 100]


Puede ver que el primer parámetro strings,, es una matriz que contiene todos los literales de cadena:



"This is a string with "
" and "
" and "
" interpolated inside."


Este argumento también tiene una propiedad a la rawque puede hacer referencia strings.raw. Contiene una línea en la que no se han procesado secuencias de escape. Por ejemplo, \nserá solo un carácter \n, no un comando de avance de línea.



El segundo argumento ,, ...expressionses una matriz que contiene todas las expresiones:



true
false
100


El resultado es que taglas expresiones y literales de cadena se pasan a la función de plantilla de etiqueta . Tenga en cuenta que la función no es necesaria para devolver una cadena. Puede trabajar con los valores que se le pasan y devolver cualquier cosa. Por ejemplo, podríamos tener una función que no presta atención a nada y simplemente regresa null. Así es como se escribe la función returnsNullen el siguiente ejemplo:



function returnsNull(strings, ...expressions) {
  return null
}

const string = returnsNull`Does this work?`
console.log(string)


Como resultado de ejecutar este código, aparecerá lo siguiente en la consola:



null


Como ejemplo de lo que puede hacer en una plantilla etiquetada, puede realizar cambios en cada una de las expresiones, como cambios para incluir expresiones en etiquetas HTML. Creemos una función boldque agregue etiquetas <strong>tanto </strong>al principio como al final de cada expresión:



function bold(strings, ...expressions) {
  let finalString = ''

  //    
  expressions.forEach((value, i) => {
    finalString += `${strings[i]}<strong>${value}</strong>`
  })

  //    
  finalString += strings[strings.length - 1]

  return finalString
}

const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`

console.log(string)


Aquí, expressionsse usa un bucle forEach para recorrer la matriz . Cada elemento está incluido en etiquetas <strong></strong>.



This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.


En bibliotecas de JavaScript populares, puede encontrar varios ejemplos de uso de plantillas de etiquetas. Por ejemplo, la biblioteca graphql-tag usa un literal de plantilla gqlpara analizar cadenas de consulta GraphQL y transformarlas en un árbol de sintaxis abstracta (AST) que GraphQL entiende:



import gql from 'graphql-tag'

//        5
const query = gql`
  {
    user(id: 5) {
      firstName
      lastName
    }
  }
`


La funcionalidad de la plantilla etiquetada también se usa en la biblioteca de componentes con estilo , lo que le permite crear nuevos componentes React a partir de elementos DOM regulares y aplicarles estilos CSS adicionales :



import styled from 'styled-components'

const Button = styled.button`
  color: magenta;
`

// <Button>     


Alternativamente, puede usar el método String.raw estándar para aplicarlo a plantillas etiquetadas para evitar el procesamiento de secuencias de escape:



const rawString = String.raw`I want to write /n without it being escaped.`
console.log(rawString)


Lo siguiente aparecerá en la consola después de ejecutar este código:



I want to write /n without it being escaped.


Salir



En este artículo, recordamos la información básica sobre los literales de cadena ordinarios, formateados con comillas simples o dobles, y también hablamos sobre los literales de plantilla y las plantillas de etiquetas. Los literales de plantilla simplifican muchas tareas de procesamiento de cadenas. En particular, estamos hablando de incrustar diferentes valores en cadenas y de crear cadenas de varias líneas sin utilizar la concatenación o el escape. El etiquetado es una función de literal de plantilla avanzada útil que se utiliza en muchas bibliotecas populares.



¿Utiliza literales de plantilla?






All Articles