Mendapatkan Literal dengan String Template ES6

Addy Osmani
Addy Osmani

String di JavaScript secara historis terbatas, tidak memiliki kemampuan yang diharapkan berasal dari bahasa seperti Python atau Ruby. String Template ES6 (tersedia di Chrome 41+), ubah secara mendasar. Mereka memperkenalkan cara untuk mendefinisikan {i>string<i} dengan {i>domain-specific languages<i} (DSL), yang menghadirkan:

  • Jenis interpolasi string
  • Ekspresi yang disematkan
  • String multibaris tanpa peretasan
  • Pemformatan string
  • Pemberian tag string untuk escape HTML yang aman, pelokalan, dan lainnya.

Alih-alih mengisi fitur lain ke dalam String seperti yang kita kenal saat ini, String Template memperkenalkan cara yang benar-benar berbeda untuk memecahkan masalah ini.

Sintaksis

String template menggunakan tanda petik terbalik (``), bukan tanda kutip tunggal atau ganda yang biasa digunakan dengan string reguler. Dengan demikian, string template dapat ditulis sebagai berikut:

var greeting = `Yo World!`;

Sejauh ini, String Template tidak memberi kita lebih dari string biasa. Mari kita ubah.

Substitusi String

Salah satu manfaat nyata pertama mereka adalah substitusi string. Substitusi memungkinkan kita mengambil ekspresi JavaScript yang valid (termasuk, misalnya, penambahan variabel) dan di dalam Template Literal, hasilnya akan menjadi output sebagai bagian dari string yang sama.

String Template dapat berisi placeholder untuk penggantian string menggunakan sintaksis ${ }, seperti yang ditunjukkan di bawah:

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

// => "Yo, Brendan!"

Karena semua substitusi string di String Template adalah ekspresi JavaScript, kita dapat mengganti lebih banyak dari nama variabel. Misalnya, di bawah ini kita dapat menggunakan interpolasi ekspresi untuk menyematkan beberapa matematika inline yang dapat dibaca:

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.

Keduanya juga sangat berguna untuk fungsi di dalam ekspresi:

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

${} berfungsi dengan baik dengan jenis ekspresi apa pun, termasuk ekspresi anggota dan panggilan metode:

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

Jika Anda memerlukan tanda kutip terbalik di dalam string, string tersebut dapat di-escape menggunakan karakter garis miring terbalik \ seperti berikut:

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

String Multigaris

String multibaris dalam JavaScript telah memerlukan solusi praktis selama beberapa waktu. Solusi saat ini mengharuskan string berada dalam satu baris atau dibagi menjadi string multibaris menggunakan \ (garis miring terbalik) sebelum setiap baris baru. Contoh:

var greeting = "Yo \
World";

Walaupun seharusnya berfungsi dengan baik di sebagian besar mesin JavaScript modern, perilaku itu sendiri masih merupakan peretasan. Kita juga dapat menggunakan penyambungan string untuk memalsukan dukungan multibaris, tetapi hal ini juga menyisakan sesuatu yang diinginkan:

var greeting = "Yo " +
"World";

String template menyederhanakan string multibaris secara signifikan. Cukup sertakan baris baru di tempat yang dibutuhkan dan BOOM. Berikut contohnya:

Setiap spasi kosong di dalam sintaksis backtick juga akan dianggap sebagai bagian dari string.

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

Template yang Diberi Tag

Sejauh ini, kita telah melihat penggunaan String Template untuk substitusi string dan untuk membuat string multibaris. Fitur canggih lain yang mereka bawa adalah template yang diberi tag. Template yang Diberi Tag mengubah String Template dengan menempatkan nama fungsi sebelum string template. Contoh:

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

Semantik string template yang diberi tag sangat berbeda dengan semantik. Pada intinya, mereka adalah jenis panggilan fungsi khusus: "desugars" di atas menjadi

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

Perhatikan bagaimana argumen (n + 1) th sesuai dengan substitusi yang terjadi antara entri ke-n dan (n + 1) dalam array string. Ini dapat berguna untuk segala macam hal, tetapi salah satu yang paling mudah adalah escape otomatis dari variabel interpolasi.

Misalnya, Anda dapat menulis fungsi escape HTML sedemikian rupa.

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

mengembalikan {i>string<i} dengan variabel yang sesuai sebagai pengganti, tapi dengan semua karakter HTML yang tidak aman diganti. Mari kita lakukan. Fungsi escape HTML akan menggunakan dua argumen: nama pengguna dan komentar. Keduanya mungkin berisi karakter HTML yang tidak aman (yaitu ', ", <, >, dan &). Misalnya, jika nama pengguna adalah "Domenic Denicola" dan komentarnya adalah "& is a fun tag", kita akan menghasilkan output:

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

Solusi template kami yang diberi tag dapat ditulis sebagai berikut:

// 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"

Penggunaan lain yang mungkin termasuk escape otomatis, pemformatan, pelokalan, dan secara umum, substitusi yang lebih kompleks:

// 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}`;

Ringkasan

String Template tersedia di Chrome 41 beta+, IE Tech Preview, Firefox 35+, dan io.js. Secara praktis, jika Anda ingin menggunakannya dalam produksi saat ini, fungsi tersebut didukung dalam Transpiler ES6 utama, termasuk Traceur dan 6to5. Lihat contoh String Template kami di repositori contoh Chrome jika Anda ingin mencobanya. Anda mungkin juga tertarik dengan ES6 Setara dalam ES5, yang menunjukkan cara mencapai beberapa String Template sugaring yang dibawa menggunakan ES5 saat ini.

String Template menghadirkan banyak kemampuan penting bagi JavaScript. Ini mencakup cara yang lebih baik untuk melakukan interpolasi string & ekspresi, string multibaris, dan kemampuan untuk membuat DSL Anda sendiri.

Salah satu fitur paling signifikan yang dibawanya adalah template yang diberi tag - fitur penting untuk penulisan DSL semacam itu. Fungsi ini menerima bagian dari String Template sebagai argumen dan Anda kemudian dapat memutuskan cara menggunakan string dan substitusi tersebut untuk menentukan output akhir string.

Bacaan Lebih Lanjut