반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 러스트
  • 참조 해제
  • 자바
  • 플라이웨이트패턴
  • prerendering
  • Pre-rendering
  • 싱글턴
  • 이펙티브 자바 item9
  • 이펙티브자바
  • 서버리스 컴퓨팅
  • 메이븐 골
  • 알고리즘
  • serverless computing
  • 자바스크립트 면접
  • 자바 검증
  • Java
  • rust
  • pnpm
  • bean Validation
  • 느린 쿼리
  • 프로그래머의 뇌
  • 자바스크립트
  • 객체복사
  • 싱글톤
  • 스프링 검증
  • next js app
  • 자료구조
  • Javadoc 자바독 자바주석 주석 Comment
  • 자바스크립트 인터뷰
  • 자바 디자인패턴
  • try-with-resources
  • item9
  • 디자인패턴
  • MSSQL
  • 도커공식문서
  • Next.js
  • NEXT JS
  • item8
  • 팩터리 메서드 패턴
  • 메이븐 라이프사이클
  • 이펙티브 자바
  • 슬로우 쿼리
  • 작업기억공간
  • 외래키 제약조건
  • 추상 팩터리 패턴
  • 싱글톤 패턴
  • 메이븐 페이즈
  • 빈 검증
  • item7
  • 토비의 스프링

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

자바스크립트/모던 자바스크립트

모던 자바스크립트, 템플릿 리터럴과 템플릿 태그 함수

2023. 3. 8. 23:06

템플릿 리터럴

  • 정규표현식 리터럴(//g), 문자열 리터럴(""), 배열 리터럴([]) 처럼 리터럴의 한 종류이다.
  • 백틱( ` )으로 구분되는 리터럴이며, 악센트(accent)라고도 한다.
  • 리터럴 중간에 Place Holder (${}) 를 이용하여 표현식을 리터럴에 삽입할 수 있다.
    • 문자열을 이용할 때 "myName = " + name 과 같은 행위를 편하게 만들어준다.
  • 이스케이프 시퀀스는 일반 문자열과 동일하게 동작한다.
    • \n 가 중간에 온다면, 동일하게 개행으로 취급되는 것을 볼 수 있다.

리터럴이란, 더이상 쪼갤 수 없는 값의 표현이다.
심볼(Symbol()) 도 리터럴이다.

기본 사용법

const name = "jake";
console.log(`my name is ${name}`);

const employees = ["jack", "paul", "haul"];
console.log(`our company has ${employees.join(", ")}`);

재사용 팁

const name = "jake";
const age = "20";
const height = "193cm";

console.log(`name: ${name}, age: ${age}, height: ${height}`);
  • console.log() 를 이용해 한번 출력해버리면 템플릿이 사라진다.
const introduce = ({ name, age, height }) =>
  `name: ${name}, age: ${age}, height: ${height}`;
  • 초보적인 내용이지만, 이렇게 함수로 래핑하면 자연스레 재사용이 가능해진다.

템플릿 태그 함수 (Tagged templates)

사실상 템플릿 리터럴이야 30초면 이해하고 코드에 적용하지만, 태그 함수의 경우는 아마 적용해서 쓰고 있는 사람이 많진 않을 것이라 생각한다.

  • 템플릿 리터럴을 이용해 함수를 호출하는 방식을 말한다.
  • 문자열을 조작하거나 포맷팅할 때 특히 유용하다.
  • 반복하여 문자열 조작 작업을 할 때 태그 함수를 통해 캡슐화가 가능하다.
    • 코드가 더 모듈화되고 재사용성이 뛰어난 형태로 변한다.

기본 사용법

const a = 1;
const b = 2;
const c = 3;

const templateTag = (template, ...args) => {
  console.log("template", template);
  console.log("args", args);
};

templateTag`a = ${a}, b = ${b}, c = ${c}`;

// template (4) ['a = ', ', b = ', ', c = ', '', raw: Array(4)]
// args (3) [1, 2, 3]
  • 함수에 인자를 넘길 때, 템플릿 문자열 부분과 치환자 부분이 순서대로 넘어온다.
  • ...values 를 통해 치환자 부분을 받은 이유는 치환자 몇 개가 넘어올지 확신할 수 없기 때문이다.
  • template 부에 raw 라고 하는 배열이 있는데, 이는 이스케이프 전의 문자열을 갖고 있다.
    • 만일 \n 을 넣었다면, raw 에는 개행이 아니라 문자열 그대로의 \n 가 담겨 있다.

raw 를 사용하는 예제

const example = (template) => {
  console.log("template[0]", template[0]);
  console.log("template.raw[0]", template.raw[0]);
};

example`\u000A\x0a\n`;

/*
template[0] 


*/

/*
template.raw[0] \u000A\x0a\n
*/
  • template[0] 에서는 \u000A\x0a\n 이 전부 개행으로 변환되어서 개행만 보인다.
  • template.raw[0] 에선 개행으로 변환되지 않은 날것의 문자열을 보여주고 있다.
const example2 = (template) => {
  console.log("template", template);
  console.log("template.raw", template.raw);
};

example2`Has invalid escape: \ufoo${","}Has only valid escapes:\n`;

/*
template (2) [undefined, 'Has only valid escapes:\n', raw: Array(2)]
template.raw (2) ['Has invalid escape: \\ufoo', 'Has only valid escapes:\\n']
*/
  • 유효하지 않은 이스케이프 시퀀스는 undefined 로 치환된다.
  • \ufoo 는 유효한 유니코드 문자가 아니다.
    • 코드 포인트 \u0041 (65) 은 A 로 표현된다

raw 는 이스케이프가 일어나지 않는다는 점을 활용하여 정규표현식을 작성하기에도 좋다.
정규표현식 리터럴이 따로 존재하는 이유는 이스케이프 등 일반 문자열 리터럴에서는 예외가 너무 많기 때문이다.

raw 로 정규표현식 객체를 만드는 예제

const createRegex = (template, ...values) => {
  const source = template.raw.reduce(
    (acc, str, index) => acc + values[index - 1] + str
  );

  const match = /^\/(.+)\/([a-z]*)$/.exec(source);

  if (!match) {
    throw new Error("Invalid regular expression");
  }

  const [, expr, flags = ""] = match;
  return new RegExp(expr, flags);
};

const escapeRegExp = (s) => String(s).replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
const alternatives = ["this", "that", "the other"];
const rex = createRegex`/\b(?:${alternatives.map(escapeRegExp).join("|")})\b/i`;

console.log(
  `alternatives.map(escapeRegExp).join("|")`,
  alternatives.map(escapeRegExp).join("|")
);

console.log("rex", rex);

const test = (str, expect) => {
  const result = rex.test(str);
  console.log(`str: ${result}, ${result === expect ? "GOOD" : "BAD"}`);
};

test("doesn't have either", false);
test("has_this_but_not_delimited", false);
test("has this", true);
test("has the other ", true);
  • 문자가 포함되어 있는지 확인하는 간단한 정규표현식 예제이다.

간단 DSL 예제

const html = (strings, ...values) => {
  const joined = strings.reduce((result, string, i) => {
    result += string;

    if (values[i]) {
      result += values[i];
    }

    return result;
  }, "");

  // Parse the joined string as an HTML element
  const parser = new DOMParser();
  const parsed = parser.parseFromString(joined, "text/html");
  return parsed.body.firstChild;
};

const message = "Hello World!";

const elem = html`
  <div class="container">
    <h1>${message}</h1>
    <p>This is a paragraph.</p>
  </div>
`;

console.log(elem);
document.body.appendChild(element);
  • 얼핏 보면, 'element.innerHTML = xxx 와 무슨 차이가 있나?' 와 같은 생각을 하기 쉽다.
  • 태그 중간중간에 나오는 placeholder 에 해당하는 값을 하나씩 검증하거나 필터링하거나 매핑할 때 매우 유리하다.

간단 DSL 예제 발전시키기

const insertHTML =
  (selector, { position = "beforeend", prefix = "", suffix = "" }) =>
  (strings, ...values) => {
    const $selected = document.querySelector(selector);

    if ($selected) {
      const htmlString = strings.reduce((result, string, i) => {
        result += string;

        if (values[i]) {
          result += prefix + values[i] + suffix;
        }

        return result;
      }, "");

      $selected.insertAdjacentHTML(position, htmlString);

      return;
    }

    console.warn(
      `selector: ${selector} 에 해당하는 엘리먼트가 존재하지 않습니다.`
    );

    return;
  };

const content = "myButton";

insertHTML("#dpHeader", { prefix: "(", suffix: ")" })`
  <button>${content}</button>
`;
  • selector 를 통해 엘리먼트를 선택하고 해당 엘리먼트에 DOM Element 를 삽입한다.
  • DOM 엘리먼트에 삽입되는 Place holder 에 대해 prefix 와 suffix 도 주었다.
반응형
저작자표시 비영리

'자바스크립트 > 모던 자바스크립트' 카테고리의 다른 글

모던 자바스크립트, 편의 유틸 문자열 메서드  (0) 2023.03.12
모던 자바스크립트, UTF-16 이슈 해결에 관련된 문자열 함수  (0) 2023.03.11
모던 자바스크립트, 비동기 버전의 이터레이터, 이터러블, 제너레이터  (0) 2023.02.28
모던 자바스크립트, async await  (0) 2023.02.28
모던 자바스크립트, 제너레이터 (Generator)  (0) 2023.02.28
    '자바스크립트/모던 자바스크립트' 카테고리의 다른 글
    • 모던 자바스크립트, 편의 유틸 문자열 메서드
    • 모던 자바스크립트, UTF-16 이슈 해결에 관련된 문자열 함수
    • 모던 자바스크립트, 비동기 버전의 이터레이터, 이터러블, 제너레이터
    • 모던 자바스크립트, async await
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바