
여러 곳에서 Template Literal은 꾸준하게 잘 사용해온 좋은 문자열 표기법입니다. 특히 vanilla Javascript로 렌더링하는 법을 연습할 때나 react의 styled-components를 사용할 때 Template Literal을 정말 많이 사용했습니다.
하지만 Template literal의 정확한 특징을 학습해본 적이 없었습니다. Template Literal은 어떤 기능들을 위해서 사용해야 할까요? 또 어떤 특징이 있기 때문에 Template Literal을 styled-components와 같은 형식으로 사용할 수 있는 걸까요? 이의 내용을 MDN 공식 문서를 기반으로 학습해 보았습니다.
Template Literal 은 backtick(`)으로 구분된 문자열 리터럴
ES6에서는 템플릿 리터럴(Template literal)이라고 불리는 새로운 문자열 표기법을 도입했습니다.
`string text`
`string text line 1
string text line 2`
`string text ${expression} string text`
tag `string text ${expression} string text`
템플릿 리터럴은 일반적으로 큰 따옴표(”), 작은 따옴표(’)로 작성되는 문자열과는 다른 특징을 가지고 있고 이를 통해 여러 활용법으로 사용할 수 있습니다.
백틱(`)으로 표현된 문자열은 줄바꿈을 인식하고 그대로 표현하게 됩니다.
즉 \n 을 적지 않고, 백틱 내에서 줄바꾼 내용을 그대로 출력할 수 있습니다.
// 아래의 두 코드는 동일한 값을 출력합니다.
console.log("first line 1\nsecond line 2")
console.log(`first line 1
second line 2`)
표현식(expression)에 일반 문자열을 삽입하는 방법입니다.
${변수}의 표현을 통해 백틱(`) 안의 표현식에 변수의 값을 문자열로 넣어줄 수 있습니다.
표현식 삽입법을 활용하면 복잡한 문자 간의 연산 없이 변수를 넣은 문자열을 만들 수 있습니다.
var a = 5;
var b = 10;
// (")을 사용한 일반 표현법
console.log("Fifteen is " + (a + b) + " and\nnot" + (2 * a + b) + ".")
// (`)을 사용한 표현볍
console.log(`Fifteen is ${a + b} and
not ${2 * a + b).`);
Template Literal을 중첩하여 문자열을 표현함으로써, 읽고 쓰기 쉬운 코드를 작성하게 해줍니다.
${변수}의 변수에서 Template Literal을 작성함으로 중첩된 Template Literal을 작성할 수 있습니다.
// ES5 방식
var classes = "header"
classes += isLargeScreen()
? ""
: item.isCollapsed
? " icon-expander"
: " icon-collapser";
// ES2015, 중첩 없는 템플릿 리터럴
const classes = `header ${
isLargeScreen() ? "" : item.collapsed ? "icon-expander" : "icon-collapser"
}`;
// ES2015, 중첩 템플릿 리터럴
const classes = `header ${
isLargeScreen() ? "" : `icon-${item.collapsed ? "expander" : "collapser}`
}`;
Tagged templates는 template literal의 더 발전한 형태입니다.
태그 함수는 parameter로 (”문자열의 배열”, 표현식 변수1, 표현식 변수2, …)의 값을 받아 내부에서 값을 연산하여 반환하게 됩니다.
${변수} 로 잘라내어 만들어낸 배열${변수}의 값으로 백틱 내 존재하는 만큼 표현식 변수가 존재var hello = 11;
var world = "hello world";
function tagExample(strings, variable1, variable2) {
var str0 = strings[0];
var str1 = strings[1];
var str2 = strings[2];
// strings = ["this is ", " and ", " test"]
var example;
if (variable1 > 10) {
example = "A"
} else {
example = "B"
}
// variable1 : hello = 11
// variable2 : world = "hello world
return str0 + varibale2 + str1 + example + str2
}
var output = tagExample`this is ${hello} and ${world} test`
console.log(output)
// this is world and hello A test
태그 함수는 문자열 뿐만 아니라 함수와 같은 어떤 것이라도 반환할 수 있습니다.
// 함수를 반환
function template(strings, ...keys) {
return function (...values) {
var dict = values[values.length - 1] || {};
var result = [strings[0]];
keys.forEach(function (key, i) {
var value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join("");
};
}
var t1Closure = template`${0}${1}${0}!`;
t1Closure("Y", "A"); // "YAY!"
var t2Closure = template`${0} ${"foo"}!`;
t2Closure("Hello", { foo: "World" }); // "Hello World!"
템플릿의 raw() property를 사용한다면 escape sequence를 처리하지 않은 값 자체에 접근할 수 있습니다.
function tag(strings) {
console.log(strins.raw[0]
}
tag`string text 1\n string line 2`;
// string text 1\n string line 2 이 출력된다.
// \n이 줄바꿈 처리 되지 않고 단어 그 자체로 출력
Template Literal은 그저 변수를 포함한 String을 동적으로 표현하기 좋은 문자열 표현 방식으로만 알고 있었습니다. 하지만 Tagged Templates라는 함수로의 활용 방식을 통해, 사용자들이 쉽게 구현할 수 있는 함수들을 만들기 좋은 방식이라는 것을 배울 수 있었습니다.(Styled-components라던가) 한번 기회가 된다면 Tagged Templates을 적절한 방식으로 활용해봐야 겠습니다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
https://poiemaweb.com/es6-template-literals