Búsqueda de sitios web

javascript - Literales de plantilla y llamadas a funciones sin paréntesis


Recientemente aprendí que ES6 permite hacer llamadas a funciones sin paréntesis cuando se usa un literal de plantilla como parámetro. Por ejemplo.

showstring`Hello World`;

Sin embargo, después de leer algunos artículos sobre esta funcionalidad, me he quedado con poca información sobre la lógica detrás de cómo JS maneja estas llamadas.

Después de jugar con algunas permutaciones de mi código, todavía estoy luchando por unir el patrón de cómo se descompone un literal de plantilla dentro de la función cuando uno lo llama de esa manera.

const showstring = (str) => {
  console.log(str);
}
showstring`Hello World`;

Lo que sucede en el código anterior es sencillo, el literal de cadena se recibe como un arreglo donde el primer y único elemento es la cadena.

Donde se vuelve un poco confuso es una vez que empiezo a usar expresiones dentro de la plantilla. Por ejemplo.

const showstring = (str, ...values) => {
  console.log(str);
  console.log(values)
}
const name = 'John'
showstring`Hello World ${name} ${name} ${1 + 2} and more`;

Entonces parece que la parte ...values desestructura todas las expresiones. Pero, entonces, ¿por qué el arreglo str tiene cadenas vacías en esos lugares?

Simplemente no entiendo completamente el patrón que sigue aquí. ¿Alguien puede explicar esta función? ¿O tal vez señalarme un buen artículo?

Respuesta #1

En el segundo fragmento de código, estos se registran:

// str
[
  "Hello World ",
  " ",
  " ",
  " and more"
]

// values
[
  "John",
  "John",
  3
]

Si con esos "strings vacíos" te refieres al segundo y tercer elemento del array str, no son strings vacíos; son strings con un solo espacio. Provienen de los espacios entre las expresiones en el literal de plantilla:

showstring`Hello World ${name} ${name} ${1 + 2} and more`;
//                            ^       ^

Cuando un literal de plantilla va precedido por una expresión, en este caso showstring, se llama plantilla etiquetada.

En tu función showstring, str siempre contiene un elemento más que el arreglo values. Por ejemplo, echa un vistazo a lo que registran estos logs:

const showstring = (str, ...values) => {
  console.log(str);
  console.log(values)
}
const name = 'John'
showstring``;
showstring`${name}`;
showstring`Hello ${name}!`;

Esto no es específico de tu función; así es como funcionan las plantillas etiquetadas. Del apartado Plantillas etiquetadas en el libro JavaScript para programadores impacientes (edición ES2020):

La función antes de la primera comilla invertida se llama función etiqueta. Sus argumentos son:

  • Cadenas de plantilla (primer argumento): un Array con los fragmentos de texto que rodean las interpolaciones $ {}.
  • Sustituciones (argumentos restantes): los valores interpolados.

Sobre tu comentario:

Sin embargo, curiosamente, ese único espacio siempre permanecerá como un solo espacio sin importar cuántos espacios pongas entre las expresiones al llamar a la función. ¿Alguna idea de por qué se reduce a un solo espacio?

Esto no parece ser el caso. Esto registra una cadena con tres espacios:

const showstring = (str, ...values) => {
  console.log(str);
  console.log(values)
}
const name = 'John'
showstring`Hello ${name}   ${name}!`;

¿Tal vez estabas imprimiendo los resultados en el DOM? Los espacios múltiples se muestran como solo uno a menos que estés usando <pre> o white-space: pre; o algo similar, así que podría parecer que los resultados se recortan a solo un espacio.