Теги для шаблонных строк

  —  3 минуты

#web#javascript#theory#data#code
Читать статью в Telegram

В JavaScript есть, как по мне, крайне странный синтаксис. Самым очевидным его применением можно считать styled-components и выглядит всё это примерно так:

javascript
1const display = 'flex';
2
3const Button = styled.button`
4    padding: 10px;
5    color: red;
6    display: ${display}
7`
8

В результате выполнения этого чуда мы получим компонент на основе нативного button с предустановленными стилями из литералов

Но вы когда нибудь задумывались, что styled.button — это тоже функция? А как она вызывается? Как устроена внутри?

На самом деле, самый базовый пример такого синтаксиса можно рассмотреть так:

javascript
1function foo(strings, ...values) {
2    let result = strings[0];
3
4    values.forEach((value, index) => {
5        result += value + strings[index + 1];
6    });
7
8    return result;
9}
10

Всё, что делает эта функция — собирает строку из шаблона и подставленных переменных

  • strings — массив строк, содержащий все части текста, разделенные переменными
  • values — массив значений, которые вставляются внутрь шаблона

Попробуем вызвать нашу функцию:

javascript
1const name = "Денис"
2const channel = "progway"
3
4foo`Меня зовут ${name} и я люблю ${channel}`
5

Использование обратных кавычек после именования функции вызывает эту самую функцию

Для нашего примера, strings — это:

javascript
1[
2    "Меня зовут ",
3    " и я люблю ",
4    ""
5]
6

а values:

javascript
1[
2    "Денис",
3    "progway"
4]
5

По такому же принципу и работает styled-components, конечно же, с более сложной логикой внутри

Этот синтаксис очень специфичный, ему не так много применений, но всё таки в некоторых случаях он бывает очень удобен. Например, в призме, с помощью такого такого синтаксиса можно кинуть запрос в БДшку

В реальной жизни вам скорее всего не понадобится писать подобные функции, но вдруг..

Ещё один пример

Бывает такое, что нужно встроить в строку значение, которое может быть пустым. Обычно пишутся доп. проверки:

javascript
1const order = {
2  city: "Москва" // представим, что возможно undefined или null
3}
4
5const { city } = order
6
7// могут писать что-то типа такой проверки
8city ? `Ваш город: ${city}` : null
9

Можно решить эту же задачу с помощью функции из поста выше, вот так это будет:

typescript
1type SubstitutionPrimitive = string | number | boolean | undefined | null;
2
3const isNullOrUndefined = (value: SubstitutionPrimitive): value is undefined | null => {
4  return value === undefined || value === null;
5};
6
7const safePaste = (strings: TemplateStringsArray, ...substitutions: SubstitutionPrimitive[]) => {
8  let result = strings[0];
9
10  for (let index = 0; index < substitutions.length; index++) {
11    const value = substitutions[index];
12
13    if (isNullOrUndefined(value)) return null;
14
15    result += value + strings[index + 1];
16  }
17
18  return result;
19};
20

Просто вернем null вместо строки, если какое либо из значений в подстановках null или undefined. Вот так это будет вызываться:

javascript
1const apple = {
2    name: 'Яблоко',
3};
4const orange = {};
5
6safePaste`Товар: "${apple?.name}"`;
7// Товар: "Яблоко"
8
9safePaste`Товар: "${orange?.name}"`;
10// null
11

Ну типа костыль. А вроде и нет. Просто ещё один пример посмотреть как это можно применить

Статья была полезной?