게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌24 - ECMAScript - 7년 전 등록 / 6년 전 수정

ES2015 Tagged Template Literal

안녕하세요. 이번 시간에는 Tagged Template Literal에 대해 알아보겠습니다. 원래 ES6 템플릿 문자열 강좌에 들어가야 하는 내용인데요. 그동안 한 번도 써본 적이 없어서 내용에 담지 않았다가 생각보다 유용한 것 같아서 따로 강좌를 만들었습니다. 저는 이걸 똑똑한 문자열이라고 별명지어줬습니다.

요즘 ES6가 많이 사용되면서 템플릿 문자열은 많이 쓰이는데요. 태그가 붙은 템플릿 문자열은 한 번도 본 적이 없는 분들도 많을 겁니다. React를 하시는 분은 styled component를 쓰면서 가끔 보셨을 것입니다.

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

위와 같은 문법인데요. 템플릿 리터럴 앞에 styled.h1이라는 객체의 속성이 붙어 있습니다. 사실 h1은 메서드(함수)입니다. 태그 함수라고 불러도 되겠네요. 함수 뒤에 템플릿 리터럴을 붙여 같이 사용하는 것입니다. 직접 만들어보겠습니다.

const tag = (...args) => console.log(args);
tag`너의 정체가 도대체 뭐니?`; // [["너의 정체가 도대체 뭐니?", raw: ['너의 정체가 도대체 뭐니']]]

화살표 함수에는 arguments를 못 쓴다는 거 아시죠? 대신 ...args로 가져올 수 있습니다. 첫 번째 매개변수로 문자열이 담긴 배열을 가져오네요. 배열 안에 요소가 하나밖에 없는데 왜 배열을 쓴 것일까요? 그리고 배열의 요소가 아니라 속성인 raw의 정체는 무엇일까요?

다음과 같이 변수를 넣어 바꿔보겠습니다. 템플릿 리터럴을 쓰는 이유가 아래처럼 변수를 쉽게 연결하여 문자열로 만들어주기 때문이죠.

const a = '정체가';
const b = '뭐니?';
tag`너의 ${a} 도대체 ${b}`; // [['너의 ', ' 도대체 ', ' ', raw: ['너의 ', ' 도대체 ', '']], '정체가', '뭐니?']

첫 번째 매개변수인 배열에는 문자 부분만 들어있고, a,와 b는 각각 두 번째, 세 번째 매개변수로 들어간 것을 확인 할 수 있습니다. 즉, 순수한 문자열들은 첫 번째 매개변수인 배열에 들어가고, a와 b는 두 번째, 세 번째 매개변수로 차례로 들어가는 것이죠. a와 b가 들어간다기 보다는 것이 아니라 첫 번째 ${} 그룹의 값과 두 번째 ${} 그룹의 값이 들어간다고 표현하는 게 정확합니다.

문자열 매개변수와 ${} 그룹 매개변수들을 분리하는 게 보기 더 좋을 것 같습니다.

const tag1 = (strs, ...vars) => console.log(strs, vars, strs.raw);
tag1`너의 ${a} 도대체 ${b}`; // ['너의 ', ' 도대체 ', ''] ['정체가', '뭐니?'] ['너의', ' 도대체 ', '']

raw 속성은 어떤 때에 써야 유용할지를 아직 찾지 못했습니다. 유용한 사용처를 알려주시면 좋겠습니다.

이 기능을 사용해 특수한 문자열을 만들 수 있습니다. 자체로는 문자열로 기능하지만 특정 행동을 취하는 똑똑한 문자열이 되는 것이죠. 두 가지 예시를 제가 만들어보았습니다.

const consoleLog = (strs, ...vars) => {
  const string = strs.reduce((prev, cur, i) => prev + strs[i] + (vars[i] || ''), '');
  console.log(string); // 여기에 똑똑한 문자열이 하면 되는 행동을 넣어줍니다.
  return string;
}

제가 자바스크립트에서 제일 좋아하는 메서드인 reduce를 사용했습니다. strs와 vars를 사용해 기존 문자열을 만드는 함수입니다. 기존 문자열을 반환하지만 반환하기 전에 콘솔에 로그를 찍습니다.

보통 개발 시에 console.log 많이 찍으시죠? 이걸 위의 함수로 한 줄로 줄일 수 있습니다.

const str = `너의 ${a} 도대체 ${b}`;
console.log(str);

해야할 것을 아래처럼 한 줄로 할 수 있습니다.

consoleLog`너의 ${a} 도대체 ${b}`;

또한 문자열 sanitization에도 쓸 수 있습니다. SQL 인젝션같은 것을 막을 때 좋죠.

const engAndNumOnly = (strs, ...vars) => {
  const string = strs.reduce((prev, cur, i) => prev + strs[i] + (vars[i] ? vars[i].replace(/[^A-z0-9]/g, ''): ''), '');
  return string;
}

const c = 'English와 한글';
const d = '0-9 and !@#';
engAndNumOnly`Yo! ${c} ${d}`; // "Yo! English 09and"

영어랑 숫자만 허용하는 템플릿 문자열을 만드는 태그 함수입니다. vars로 들어오는 값들에 영어나 숫자를 제외한 문자가 있는지 검사해서 제거합니다.

대충 어떤 식으로 사용하면 되는지 이해되셨죠? 사실 저걸로 별의별 짓을 다 할 수 있지만, 똑똑한 문자열을 만드는 것 외에는 그냥 함수를 쓰는게 훨씬 가독성이 좋습니다.

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

2개의 댓글이 있습니다.
6년 전
2번째 3번째 예제에서 주석친 결과값의 대괄호의 개수가 맞지않는것같습니다.
6년 전
감사합니다.
6년 전
글 잘읽었습니다.궁금한 점이 있는데
consoleLog`너의 ${a} 도대체 ${b}`; 를
console.log(`너의 ${a} 도대체 ${b}`) 이런식으로 해도 무방하지 않나요?
구지 consoleLog라는 함수를 만들어서 사용하는 이유가 뭔가요?
6년 전
네 저건 그냥 예시일 뿐이고요. 굳이 저렇게 할 필요는 없죠. 실제 사용 예를 보시려면 styled component 검색해보세요
7년 전
str.raw는 raw string을 보기 위해 사용합니다. 아래와 같이요.

function log(str) {
console.log(str.raw[0]);// log \u100
console.log(str[0]);// log unicode character
}
log`\u{100}`;
7년 전
저도 그건 MDN에서 봐서 알긴 하는데요. 유니코드 표시 외에는 사용할 데가 없나요? 사실 유니코드 표시는 태그 템플릿 리터럴 말고 더 좋은 방법이 많아서...