[TIL / JavaScript] 템플릿 리터럴

[TIL / JavaScript] 템플릿 리터럴

  • 내장된 표현식을 허용하는 문자열 리터럴이다.
`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`
  • 작은따옴표나( ’ ) 큰따옴표( “ ) 대신 백틱( ` )으로 문자열을 감싸준다.

Multi-line strings


console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
  • \n을 사용하지 않고도 리터럴 안에서 개행을 하면 줄바꿈할 수 있다.

Expression interpolation (표현식 삽입법)


var a = 20;
var b = 3;
var c = "군인";
var str = "나는 " + (a + b) + "살이고 " + c + "이 아니다.";
console.log(str); // 나는 23살이고 군인이 아니다.

ES6 이전에는 표현식을 위 코드와 같이 문자열에 넣었지만

let a = 20;
let b = 3;
let c = "군인";
let str = `나는 ${a+b}살이고 ${c}이 아니다.`;
console.log(str); // 나는 23살이고 군인이 아니다.
  • 템플릿 리터럴에서는 ${}를 사용하여 표현식을 삽입할 수 있다.

Nesting templates (중첩 템플릿)


var classes = 'header'
classes += (isLargeScreen() ?
   '' : item.isCollapsed ?
     ' icon-expander' : ' icon-collapser');
  • 특정 조건을 만족하는 경우마다 다른 문자열을 변수에 저장하고 싶을 때, 템플릿을 중첩해서 작성하면 가독성이 더 좋을 수 있다.
// 중첩없이 템플릿 리터럴 사용한 경우
const classes = `header ${ isLargeScreen() ? '' :
    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
// 중첩하여 템플릿 리터럴을 사용한 경우
const classes = `header ${ isLargeScreen() ? '' :
 `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;

Tagged templates


  • 태그를 사용하여 템플릿 리터럴을 함수로 파싱할 수 있다.
  • 태그 함수의 첫 번째 인수는 문자열 값의 배열이며 나머지 인수는 표현식이다.
  • 문자열 값의 배열은 표현식을 기준으로 split된다.
let person = 'Koh';
let age = 23;

// 함수명은 원하는 대로 정할 수 있다.
let tag = function(strings, personExp, ageExp) {    
    let str0 = strings[0]; // "that "
    let str1 = strings[1]; // "is a"

    let ageStr;
    if(ageExp > 99) ageStr = 'centenaian';
    else ageStr = 'youngster';

    return str0 + personExp + str1 + ageStr;
// 함수 내에서 템플릿 리터럴을 반환할 수 있다.   
};

// 함수명을 리터럴 앞에 그냥 붙여준다.
let output = tag`that ${person} is a ${age}`;
console.log(output);    //that Koh is a youngster
  • Tagged templates는 데이터별로 상황이나 조건이 다른 경우 유용하게 쓰일 수 있다.
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 데이터가 들어오는 경우, 오뚜기의 items는 아직 추가가 안되어 undefined가 출력된다.

const ramenList = [
    {
        brand: '농심',
        items: ['신라면','짜파게티','참치마요','둥지냉면']
    },
    {
        brand: '삼양',
        items: ['삼양라면', '불닭볶음면']
    },
    {
        brand: '오뚜기',
        itmes: []
    }
];

function fn(strings, brand, items) {
    let str;
    if(undefined === items) {
        str = brand + "의 라면은 재고가 없습니다!";
    } else {
        str = strings[0] + brand + strings[1] + items;
    }
    return str;
}

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}`);
// 오뚜기의 라면은 재고가 없습니다!

이렇게 Tagged templates를 이용하여 예외적인 상황을 커버할 수 있다.

Raw strings


  • String.raw 메소드를 사용하면 템플릿 문자열을 입력한 대로 출력할 수 있다.
let s = String.raw`xy\n${1+1}z`;
console.log(s); // xy\n2z
  • 태그 함수를 만들어 원래의 문자열을 반환하려면 첫 번째 인자에 raw 프로퍼티를 사용하면 된다.
let tag = function(strings) {
    return strings.raw[0];
}

let str = tag`Hello\nWorld.`;
console.log(str); // Hello\nWorld.

P.S.

✍️ 사용하기도 편리하고 기존 방식보다 가독성이 훨씬 좋아진 것을 알 수 있다. 코드를 작성하면서 직접 사용해 봐야겠다🙃

Reference


좋은 웹페이지 즐겨찾기