템플릿 리터럴이란 내장된 표현식을 허용하는 문자열 리터럴로 표현식 / 문자열 삽입, 여러 줄 문자열, 문자열 형식화, 문자열 태깅 등 다양한 기능을 제공한다.
ES6 이전에는 다음과 같이 문자열을 삽입하였다.
let name = 'Hojun';
let greeting = 'Hello my name is ' + name ;
console.log(greeting); // Hello my name is Hojun
/
ES6부터는 백틱(`) 을 이용하여 아래와 같이 더 쉽게 작성
let name = 'Hojun';
const greeting = 'Hello my name is ${name}';
console.log(greeting); // Hello my name is Hojun
ES6 이전에는 표현식을 삽입하기 위해 아래와 같이 코드를 작성하였다.
let a = 1;
let b = 10;
console.log('1 * 10 is ' + (a * b)); // 1 * 10 is 10
/
ES6에서는 백틱을 이용하여 아래와 같이 쉽게 코드를 작성할 수 있다.
let a = 1;
let b = 10;
console.log(`1 * 10 is ${a * b}`); // 1 * 10 is 10
ES6 이전에는 HTML 프래그먼트 등에 사용할 여러 줄로 이루어진 문자열을 백슬래시를 이용해 다음과 같이 작성하였다.
let text = "Hello, \
my name is Alberto \
how are you? \ ";
ES6 에서는 전체를 백틱으로 감싸기만 한다면 백슬래시 지옥을 겪지 않아도 된다 !
let text = `Hello,
my name is Alberto
how are you?`;
다음과 같이 템플릿 안에 템플릿을 중첩하는 것도 간단해졌다.
/
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>
/
위에서는 map 함수를 이용하여 people의 각 원소에 대해 반복 동작을 수행하고 people 내에 있는 name을 담아 li 태그를 표시하였다.
삼항 연산자를 사용한다면 템플릿 문자열 내에 로직을 쉽게 추가할 수 있다.
삼항 연산자의 기본 문법은 다음과 같다.
/
const isDiscounted = false;
function getPrice() {
console.log(isDiscounted ? "$10" : "$20");
}
getPrice(); // $20
다음과 같이 삼항 연산자를 이용해 작성할 수 있다.
// name, age와 함께 artist 객체 생성
const artist = {
name: "HOJUN",
age: 27,
};
// artist 객체에 song 프로퍼티가 있을 때만 문장에 추가하고,
// 없으면 아무것도 반환하지 않는다.
const text = `
<div>
<p> ${artist.name} is ${artist.age} years old ${artist.song ?
`and wrote song ${artist.song}` : '' }
</p>
</div>
`;
// <div>
// <p> HOJUN is 27 years old
// </p>
// </div>
const artist = {
name: "HOJUN",
age: 27,
song: 'Love',
};
// <div>
// <p> HOJUN is 27 years old and wrote the song Love
// </p>
// </div>
아래의 예제처럼 필요할 때 템플릿 리터럴 내에 함수를 전달할 수도 있다. ( ${groceriesList(groceries.others)} 부분 )
/
const groceries = {
meat: "pork chop",
beggie: "salad",
fruit: "apple",
others: ['mushrooms', 'instant noodles', 'instant soup'],
};
// groceries의 각 값에 대해 map()을 수행하는 함수
function groceryList (others) {
return `
<p>
${toehrs.map( other => ` <span>${other}</span>`).join('\n')}
</p>
`;
}
// p 태그 내 모든 groceries를 출력. 마지막은 others 배열의 모든 원소를 포함한다.
const markup = `
<div>
<p>${groceries.meat}</p>
<p>${groceries.veggie}</p>
<p>${groceries.fruit}</p>
<p>${groceryList(groceries.others)}</p>
</div>
`;
// <div>
// <p>pork chop</p>
// <p>salad</p>
// <p>apple</p>
// <p>
// <p>
// <span>mushrooms</span>
// <span>instant noodles</span>
// <span>instant soup</span>
// <p>
// <p>
// </div>
/
마지막 p 태그에서 함수 groceryList를 호출해 다른 모든 others를 인수로 전달했다.
함수를 태그하여 템플릿 리터럴을 실행하면 템플릿 내부에 있는 모든 항목이 태그된 함수의 인수로 제공된다.
작동 방식은 매우 간단하다.
함수 이름을 가져다 실행할 템플릿 앞에 쓰기만 하면 된다.
/
let person = "HOJUN";
let age = 27;
function myTag(strings, personName, personAge) {
// strings: ["That ", " is a ", "!"]
let str = string[1]; // " is a "
let ageStr;
personAge > 50 ? ageStr = "grandpa" : ageStr = "youngster";
return personName + str + ageStr;
}
let sentence = myTag`That ${person} is a ${age}!`;
console.log(sentence); // HOJUN is a youngster
/
위의 예제에서 myTag 함수의 첫번째 인수 strings는 let sentence 문의 전체 문자열 중 템플릿 리터럴 변수를 제외한 문자열들이 담긴 배열로 설정되고 템플릿 리터럴 변수들이 나머지 인수가 된다.
좀 풀어서 설명하자면 strings 배열의 각 원소는 템플릿 리터럴에 포함된 변수들을 구분자로 삼아 문자열을 나눈 결과와 같다.
즉 문자열은
That, ${person}, is a, ${age}, !
이렇게 5가지 부분으로 나뉘므로 변수를 제외한
["That", " is a ", "!"]
가 strings가 되는 것이다.
이에 대한 값은 배열 표기법을 사용해 중간에 있는 문자열에 접근할 수 도 있다.
let str = strings[1]; // " is a "