ES6 템플릿 문자열로 리터럴 가져오기

아디 오스마니
애디 오스마니

JavaScript의 문자열은 역사적으로 제한되어 있었기 때문에 Python이나 Ruby와 같은 언어에서 기대할 수 있는 기능이 부족했습니다. ES6 템플릿 문자열 (Chrome 41 이상에서 사용 가능)은 이 상황을 근본적으로 변화시킵니다. 도메인별 언어 (DSL)로 문자열을 정의하는 방법을 도입하여 다음과 같은 이점을 제공합니다.

  • 문자열 보간 유형
  • 삽입된 표현식
  • 핵이 없는 여러 줄 문자열
  • 문자열 형식 지정
  • 안전한 HTML 이스케이프 처리, 현지화 등의 작업을 위한 문자열 태그 지정

오늘날 우리가 알고 있는 문자열에 또 다른 기능을 채우는 대신 템플릿 문자열은 이러한 문제를 해결하는 완전히 다른 방법을 소개합니다.

문법

템플릿 문자열은 일반 문자열에서 사용되는 작은따옴표나 큰따옴표 대신 백틱 (``)을 사용합니다. 따라서 템플릿 문자열은 다음과 같이 작성할 수 있습니다.

var greeting = `Yo World!`;

지금까지 템플릿 문자열은 일반 문자열보다 더 많은 것을 제공하지 않았습니다. 이를 변경해 보겠습니다.

문자열 대체

첫 번째 실질적인 이점 중 하나는 문자열 대체입니다. 대체를 사용하면 유효한 자바스크립트 표현식 (예: 변수 추가 포함)을 사용할 수 있으며 템플릿 리터럴 내에서 결과가 동일한 문자열의 일부로 출력됩니다.

템플릿 문자열에는 아래와 같이 ${ } 구문을 사용하여 문자열 대체를 위한 자리표시자가 포함될 수 있습니다.

// Simple string substitution
var name = "Brendan";
console.log(`Yo, ${name}!`);

// => "Yo, Brendan!"

템플릿 문자열의 모든 문자열 대체 항목은 자바스크립트 표현식이므로 변수 이름보다 훨씬 더 많은 항목을 대체할 수 있습니다. 예를 들어 아래는 표현식 보간 유형을 사용하여 읽을 수 있는 인라인 계산을 삽입할 수 있습니다.

var a = 10;
var b = 10;
console.log(`JavaScript first appeared ${a+b} years ago. Wow!`);

//=> JavaScript first appeared 20 years ago. Wow!

console.log(`The number of JS MVC frameworks is ${2 * (a + b)} and not ${10 * (a + b)}.`);
//=> The number of JS frameworks is 40 and not 200.

표현식 내의 함수에도 매우 유용합니다.

function fn() { return "I am a result. Rarr"; }
console.log(`foo ${fn()} bar`);
//=> foo I am a result. Rarr bar.

${}는 멤버 표현식 및 메서드 호출을 비롯한 모든 종류의 표현식에서 잘 작동합니다.

var user = {name: 'Caitlin Potter'};
console.log(`Thanks for getting this into V8, ${user.name.toUpperCase()}.`);

// => "Thanks for getting this into V8, CAITLIN POTTER";

// And another example
var thing = 'template strings';
console.log(`Say hello to ${thing}.`);

// => Say hello to template strings

문자열 안에 백틱이 필요한 경우 다음과 같이 백슬래시 문자 \를 사용하여 이스케이프 처리할 수 있습니다.

var greeting = `\`Yo\` World!`;

여러 줄 문자열

자바스크립트의 여러 줄 문자열에는 한동안 해킹 해결책이 필요했습니다. 최신 솔루션에서는 문자열이 한 줄에 있거나 각 줄바꿈 앞에 \ (백슬래시)를 사용하여 여러 줄의 문자열로 분할해야 합니다. 예를 들면 다음과 같습니다.

var greeting = "Yo \
World";

이 작업은 대부분의 최신 JavaScript 엔진에서 잘 작동하지만 동작 자체는 여전히 해킹입니다. 문자열 연결을 사용하여 가짜 다중선을 지원할 수도 있지만 마찬가지로 필요한 것이 있습니다.

var greeting = "Yo " +
"World";

템플릿 문자열은 여러 줄의 문자열을 크게 단순화합니다. 필요한 곳에 줄바꿈과 BOOM을 포함하기만 하면 됩니다. 다음 예를 참고하세요.

백틱 구문 안에 있는 공백도 문자열의 일부로 간주됩니다.

console.log(`string text line 1
string text line 2`);

태그가 지정된 템플릿

지금까지 문자열 대체를 위해 템플릿 문자열을 사용하고 여러 줄 문자열을 만드는 방법을 살펴보았습니다. 이들이 제공하는 또 다른 강력한 기능은 태그된 템플릿입니다. 태그가 지정된 템플릿은 템플릿 문자열 앞에 함수 이름을 배치하여 템플릿 문자열을 변환합니다. 예를 들면 다음과 같습니다.

fn`Hello ${you}! You're looking ${adjective} today!`

태그된 템플릿 문자열의 의미 체계는 일반 시맨틱과 매우 다릅니다. 본질적으로 이는 특수한 유형의 함수 호출로 위의 '디슈가'를

fn(["Hello ", "! You're looking ", " today!"], you, adjective);

(n + 1)번째 인수는 문자열 배열에서 n번째와 (n+1)번째 항목 사이에서 이루어지는 대체에 해당합니다. 이는 모든 종류의 작업에 유용할 수 있지만, 가장 간단한 방법 중 하나는 보간된 변수의 자동 이스케이프 처리입니다.

예를 들어, 다음과 같은 HTML 이스케이프 함수를 작성할 수 있습니다.

html`<p title="${title}">Hello ${you}!</p>`

는 적절한 변수가 대체되었지만 HTML에 안전하지 않은 모든 문자가 대체된 문자열을 반환합니다. 그럼 시작하겠습니다. HTML 이스케이프 처리 함수는 사용자 이름과 주석, 이렇게 두 개의 인수를 취합니다. 둘 다 HTML에 안전하지 않은 문자 (예: ', ', <, >, &)를 포함할 수 있습니다. 예를 들어 사용자 이름이 'Domenic Denicola'이고 댓글이 '& is a good tag'인 경우 다음과 같이 출력해야 합니다.

<b>Domenic Denicola says:</b> "&amp; is a fun tag"

따라서 태그된 템플릿 솔루션은 다음과 같이 작성할 수 있습니다.

// HTML Escape helper utility
var util = (function () {
    // Thanks to Andrea Giammarchi
    var
    reEscape = /[&<>'"]/g,
    reUnescape = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g,
    oEscape = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        "'": '&#39;',
        '"': '&quot;'
    },
    oUnescape = {
        '&amp;': '&',
        '&#38;': '&',
        '&lt;': '<',
        '&#60;': '<',
        '&gt;': '>',
        '&#62;': '>',
        '&apos;': "'",
        '&#39;': "'",
        '&quot;': '"',
        '&#34;': '"'
    },
    fnEscape = function (m) {
        return oEscape[m];
    },
    fnUnescape = function (m) {
        return oUnescape[m];
    },
    replace = String.prototype.replace
    ;
    return (Object.freeze || Object)({
    escape: function escape(s) {
        return replace.call(s, reEscape, fnEscape);
    },
    unescape: function unescape(s) {
        return replace.call(s, reUnescape, fnUnescape);
    }
    });
}());

// Tagged template function
function html(pieces) {
    var result = pieces[0];
    var substitutions = [].slice.call(arguments, 1);
    for (var i = 0; i < substitutions.length; ++i) {
        result += util.escape(substitutions[i]) + pieces[i + 1];
    }

    return result;
}

var username = "Domenic Denicola";
var tag = "& is a fun tag";
console.log(html`<b>${username} says</b>: "${tag}"`);
//=> <b>Domenic Denicola says</b>: "&amp; is a fun tag"

다른 용도로는 자동 이스케이프 처리, 형식 지정, 현지화 및 일반적으로 더 복잡한 대체 등이 있습니다.

// Contextual auto-escaping
qsa`.${className}`;
safehtml`<a href="${url}?q=${query}" onclick="alert('${message}')" style="color: ${color}">${message}</a>`;

// Localization and formatting
l10n`Hello ${name}; you are visitor number ${visitor}:n! You have ${money}:c in your account!`

// Embedded HTML/XML
jsx`<a href="${url}">${text}</a>` // becomes React.DOM.a({ href: url }, text)

// DSLs for code execution
var childProcess = sh`ps ax | grep ${pid}`;

요약

템플릿 문자열은 Chrome 41 베타 이상, IE 기술 미리보기, Firefox 35 이상, io.js에서 사용할 수 있습니다. 사실상 지금 바로 프로덕션에 사용하려는 경우 Traceur와 6to5를 포함한 주요 ES6 트랜스파일러에서 지원됩니다. 사용해 보려면 Chrome 샘플 저장소에서 템플릿 문자열 샘플을 확인하세요. ES5의 ES6 동급 항목도 확인해 보세요. 현재 ES5를 사용하여 가져오는 슈가링 템플릿 문자열을 실행하는 방법을 보여주는 자료입니다.

템플릿 문자열은 JavaScript에 여러 가지 중요한 기능을 제공합니다. 여기에는 문자열 및 표현식 보간 유형을 수행하는 더 나은 방법, 여러 줄 문자열, 자체 DSL을 만드는 기능이 포함됩니다.

이들이 제공하는 가장 중요한 기능 중 하나는 태그된 템플릿입니다. 이는 이러한 DSL을 작성하는 데 중요한 기능입니다. 템플릿 문자열의 일부를 인수로 받습니다. 그러면 개발자는 문자열과 대체 값을 사용하여 문자열의 최종 출력을 결정하는 방법을 결정할 수 있습니다.

추가 자료