템플릿 리터럴(template literal)
ES6에 도입된 내장된 표현식을 허용하는 문자열 리터럴
표현식/문자열 삽입, 여러 줄 문자열, 문자열 형식화, 문자열 태깅 등 다양한 기능을 제공
런타임 시점에 일반 자바스크립트 문자열로 처리/변환됨
▶ 템플릿 리터럴 기본 문법
템플릿 리터럴은 작은따옴표(')나 큰따옴표(") 대신 백틱(`, grave accent)로 감싸줌
`string text` // 문자열 표현
`string text line 1
string text line 2` // 개행된 문자열 표현
var expression;
`string text ${expression} string text` // 변수값 문자열 조합
function tag() { };
tag `string text ${expression} string text` // 함수 호출 아규먼트
표현식 삽입법(Expression interpolation)
ES96 이전엔 표현식을 더하기 연산자(+)를 사용해 표현식을 일반 문자열 안에 집어넣었음
var a = 20;
var b = 8;
var c = "자바스크립트";
var str = "저는 " + (a + b) + "살이고 " + c + "를 좋아합니다.";
console.log(str); //저는 28살이고 자바스크립트를 좋아합니다.
템플릿 리터럴에서는 ${}를 사용하여 표현식을 표기할 수 있음
let a = 20;
let b = 8;
let c = "자바스크립트";
let str = `저는 ${a+b}살이고 ${c}를 좋아합니다.`;
console.log(str); //저는 28살이고 자바스크립트를 좋아합니다.
+ 연산자로 문자열을 연결해주는 것보다 가독성이 더 좋음
태그드 템플릿(Tagged templates)
태그를 사용하여 템플릿 리터럴을 함수로 파싱할 수 있음
let person = 'Lee';
let age = 28;
let tag = function(strings, personExp, ageExp) {
console.log(strings); // 첫 인수는 배열, ['that ', ' is a ', '']
console.log(personExp); // ${person}값, 'Lee'
console.log(ageExp); // ${age}값, 28
};
let output = tag`that ${person} is a ${age}`;
let myTag = function(strings, a, b, c) {
console.log(`문자열 배열 길이 : ${strings.length}`); // '문자열 배일 길이: 4'
for(let i = 0; i < strings.length; i+=1) {
console.log(`문자열 요소 [${i}]: ${strings[i]}`); // ['HTML', ', CSS', ', JavaScript', '']
}
console.log(a); // 5
console.log(b); // 3
console.log(c); // es10
}
let html = 5;
let css = 3;
let js = 'es10';
let string = myTag`HTML${html}, CSS${css}, JavaScript ${js}`;
태그드 템플릿은 데이터 별로 상황(조건이)이 다른 경우 유용하게 쓰일 수 있음
const ramenList = [
{
brand: '농심',
items: ['신라면','짜파게티','참치마요','둥지냉면']
},
{
brand: '삼양',
items: ['삼양라면', '불닭볶음면']
},
{
brand: '오뚜기',
itmes: []
}
];
console.log(`구매가능한 ${ramenList[0].brand}의 라면 : ${ramenList[0].items}`);
//구매가능한 농심의 라면 : 신라면,짜파게티,참치마요,둥지냉면
console.log(`구매가능한 ${ramenList[1].brand}의 라면 : ${ramenList[1].items}`);
//구매가능한 삼양의 라면 : 삼양라면,불닭볶음면
console.log(`구매가능한 ${ramenList[2].brand}의 라면 : ${ramenList[2].items}`);
//구매가능한 오뚜기의 라면 : undefined
ramenList 데이터가 들어오는 경우, 오뚜기의 라면 데이터는 아직 추가가 안되어 있어 그 결과로 undefined 뜸
이런 경우에 tagged templates로 해결할 수 있음
function fn(strings, brand, items) {
if(undefined === items) {
return brand + "의 라면은 재고가 없습니다!";
} else {
return strings[0] + brand + strings[1] + items;
}
}
console.log(fn`구매가능한 ${ramenList[0].brand}의 라면 : ${ramenList[0].items}`);
//구매가능한 농심의 라면 : 신라면,짜파게티,참치마요,둥지냉면
console.log(fn`구매가능한 ${ramenList[1].brand}의 라면 : ${ramenList[1].items}`);
//구매가능한 삼양의 라면 : 삼양라면,불닭볶음면
console.log(fn`구매가능한 ${ramenList[2].brand}의 라면 : ${ramenList[2].items}`);
//오뚜기의 라면은 재고가 없습니다!
여러줄 문자열(Multi-line strings)
여러 개행 줄의 문자열도 나눠서 작성할 필요가 없이 한번에 작성 가능함
console.log("string text line 1\n" + "string text line 2");
//템플릿 리터럴
console.log(`string text line 1
string text line 2`);
중첩 템플릿( Nesting templates )
템플릿 안에 템플릿을 중첩하는 것도 간단해짐
const people = [
{
name: 'HOJUN 1',
age: 27,
},
{
name: 'HOJUN 2',
age: 28,
},
{
name: 'HOJUN 3',
age: 29,
}
];
const markup = `
<ul>
${people.map(person => `<li> ${person.name} </li>`)}
</ul>
`;
console.log(markup);
// <ul>
// <li> HOJUN 1 </li>,<li> HOJUN 2 </li>, <li> HOJUN 3 </li>
// </ul>
또한 특정 조건을 만족하는 경우마다 다른 문자열을 변수에 저장하고 싶을 때, 템플릿을 중첩해서 작성하는 것이 가독성이 더 좋을 때가 있다고 함
//ES5
var classes = 'header'
classes += (isLargeScreen() ?
'' : item.isCollapsed ?
' icon-expander' : ' icon-collapser');
//ES6, Not use nesting templates
const classes = `header ${ isLargeScreen() ? '' :
(item.isCollapesd ? 'icon-expander' : 'icon-collapser')}`;
//ES6, Used nesting templates
const classes = `header ${ isLargeScreen() ? '' :
`icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;
물론 템플릿 안에 템플릿을 중첩하는 것도 간단해짐
Reference
'JS' 카테고리의 다른 글
ES-Module(ESM, ECMAScript Modules) (0) | 2024.06.11 |
---|---|
화살표 함수(Arrow Function) (1) | 2024.06.11 |
Symbol (1) | 2024.06.11 |
JavaScript OOP (new, Prototype chain, Subclassing) (0) | 2024.06.10 |
Call Stack (0) | 2024.06.10 |
댓글