ES6(ES2015)에서 도입된 템플릿 리터럴(Template Literals)은 자바스크립트의 문자열 처리 방식을 완전히 바꿨다.
템플릿 리터럴은 작은따옴표(')나 큰따옴표(") 대신 백틱(backtick, `)으로 감싸서 정의한다.
${expression} 구문을 사용해 변수, 연산, 함수 호출 결과를 문자열 중간에 바로 삽입할 수 있다.
// ES5 이전: 더하기 연산자로 문자열 연결
var a = 20;
var b = 8;
var lang = "자바스크립트";
var str = "저는 " + (a + b) + "살이고 " + lang + "를 좋아합니다.";
// ES6 템플릿 리터럴: 표현식 삽입법
const strLiteral = `저는 ${a + b}살이고 ${lang}를 좋아합니다.`;
console.log(strLiteral); // "저는 28살이고 자바스크립트를 좋아합니다."
개행 문자(\n)와 + 연결 연산자 없이, 백틱 내부에서 엔터를 입력하면 줄바꿈이 그대로 문자열에 반영된다.
// 기존 방식
console.log("string text line 1\n" + "string text line 2");
// 템플릿 리터럴
console.log(`string text line 1
string text line 2`);
삼항 연산자 등으로 조건에 따라 다른 문자열을 조합해야 할 때, 템플릿 리터럴 내부에 또 다른 템플릿 리터럴을 중첩하면 가독성을 크게 높일 수 있다.
// 1. ES5 방식: 복잡한 조건문과 문자열 연결
var classes = 'header';
classes += (isLargeScreen() ? '' : item.isCollapsed ? ' icon-expander' : ' icon-collapser');
// 2. 템플릿 중첩 미사용
const classes2 = `header ${isLargeScreen() ? '' : (item.isCollapsed ? 'icon-expander' : 'icon-collapser')}`;
// 3. 템플릿 중첩 활용: 공통 접두사 'icon-'을 유지하며 조건 분기
const classes3 = `header ${isLargeScreen() ? '' : `icon-${item.isCollapsed ? 'expander' : 'collapser'}`}`;
태그드 템플릿은 템플릿 리터럴을 함수의 인자로 파싱하여 전달하는 발전된 문법이다. 함수 이름 뒤에 소괄호 () 없이 백틱을 바로 붙여서 호출한다.
styled-component에서 사용하는 `styled.button...
문법이 태그드 템플릿으로 작동한다.
태그 함수는 템플릿 리터럴을 두 가지 종류의 인자로 분해해서 받는다.
strings): ${} 표현식을 기준으로 쪼개진 순수 정적 문자열들의 배열...expressions): ${} 안에 들어간 동적 표현식의 평가값들function myTag(strings, ...expressions) {
console.log("문자열 배열:", strings);
console.log("표현식 값들:", expressions);
}
const html = 5;
const css = 3;
const js = 'ES10';
myTag`HTML: ${html}, CSS: ${css}, JS:${js}`;
// 문자열 배열: ["HTML: ", ", CSS: ", ", JS: ", ""] (길이: 4)
// 표현식 값들: [5, 3, "ES10"] (길이: 3)
특징: 문자열 배열의 길이는 항상 표현식 개수 + 1이 된다. 마지막 템플릿 뒤에 아무 글자가 없더라도 끝에 빈 문자열(
"")이 포함된다.
태그 함수 내부에서 인자들을 직접 가공하여 조건부 텍스트 치환이나 데이터 검증을 일괄 처리할 수 있다.
const ramenList = [
{ brand: '농심', items: ['신라면', '짜파게티'] },
{ brand: '삼양', items: ['삼양라면', '불닭볶음면'] },
{ brand: '오뚜기', items: undefined } // 데이터 미입력 상태
];
function formatRamen(strings, brand, items) {
// items가 없을 때 대체 문구 출력
if (!items) {
return `${brand}의 라면은 현재 재고가 없습니다!`;
}
return `${strings[0]}${brand}${strings[1]}${items.join(', ')}`;
}
console.log(formatRamen`구매 가능한 ${ramenList[0].brand} 제품: ${ramenList[0].items}`);
// 출력: "구매 가능한 농심 제품: 신라면, 짜파게티"
console.log(formatRamen`구매 가능한 ${ramenList[2].brand} 제품: ${ramenList[2].items}`);
// 출력: "오뚜기의 라면은 현재 재고가 없습니다!"
\n, \t와 같은 이스케이프 시퀀스를 해석(줄바꿈 등)하지 않고, 작성된 문자 그대로 출력하고 싶을 때 사용한다.
String.raw 내장 태그 함수const rawStr = String.raw`xy\n${1 + 1}z`;
console.log(rawStr); // "xy\n2z" (줄바꿈되지 않고 \n 문자 그대로 출력됨)
raw 속성 접근태그 함수의 첫 번째 인자인 문자열 배열에는 .raw 프로퍼티가 포함되어 있어, 해석되지 않은 원시 텍스트를 그대로 꺼내 쓸 수 있다.
function rawTag(strings) {
return strings.raw[0];
}
const str = rawTag`Hello\nWorld`;
console.log(str); // "Hello\nWorld"