안녕하세요. 이번 시간에는 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로 들어오는 값들에 영어나 숫자를 제외한 문자가 있는지 검사해서 제거합니다.
대충 어떤 식으로 사용하면 되는지 이해되셨죠? 사실 저걸로 별의별 짓을 다 할 수 있지만, 똑똑한 문자열을 만드는 것 외에는 그냥 함수를 쓰는게 훨씬 가독성이 좋습니다.
consoleLog`너의 ${a} 도대체 ${b}`; 를
console.log(`너의 ${a} 도대체 ${b}`) 이런식으로 해도 무방하지 않나요?
구지 consoleLog라는 함수를 만들어서 사용하는 이유가 뭔가요?