Mendapatkan Literal dengan String Template ES6

Addy Osmani
Addy Osmani

String dalam JavaScript secara historis terbatas, tidak memiliki kemampuan yang mungkin diharapkan dari bahasa seperti Python atau Ruby. String Template ES6 (tersedia di Chrome 41+), secara mendasar mengubah hal tersebut. API ini memperkenalkan cara menentukan string dengan bahasa khusus domain (DSL), sehingga memberikan:

  • Interpolasi string
  • Ekspresi tersemat
  • String multibaris tanpa hack
  • Pemformatan string
  • Pemberian tag string untuk escape HTML yang aman, pelokalan, dan lainnya.

Template String memperkenalkan cara yang sama sekali berbeda untuk menyelesaikan masalah ini, bukan memasukkan fitur lain ke dalam String seperti yang kita ketahui saat ini.

Sintaksis

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

var greeting = `Yo World!`;

Sejauh ini, String Template belum memberi kita lebih dari string normal. Mari kita ubah.

Penggantian String

Salah satu manfaat nyata pertamanya adalah penggantian string. Penggantian memungkinkan kita mengambil ekspresi JavaScript yang valid (termasuk, misalnya, penambahan variabel) dan di dalam Template Literal, hasilnya akan ditampilkan sebagai bagian dari string yang sama.

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

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

// => "Yo, Brendan!"

Karena semua penggantian string dalam String Template adalah ekspresi JavaScript, kita dapat mengganti lebih dari sekadar 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.

Fungsi ini 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 semua jenis ekspresi, 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 petik terbalik di dalam string, tanda petik terbalik dapat di-escape menggunakan karakter garis miring terbalik \ sebagai berikut:

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

String Multibaris

String multibaris di JavaScript telah memerlukan solusi hacky selama beberapa waktu. Solusi saat ini untuknya mengharuskan string ada di satu baris atau dibagi menjadi string multibaris menggunakan \ (backslash) sebelum setiap baris baru. Contoh:

var greeting = "Yo \
World";

Meskipun ini akan berfungsi dengan baik di sebagian besar mesin JavaScript modern, perilakunya sendiri masih sedikit hack. Anda juga dapat menggunakan penyambungan string untuk memalsukan dukungan multibaris, tetapi hal ini juga tidak memuaskan:

var greeting = "Yo " +
"World";

String Template menyederhanakan string multibaris secara signifikan. Cukup sertakan baris baru jika diperlukan dan BOOM. Berikut contohnya:

Setiap spasi kosong di dalam sintaksis tanda petik terbalik 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 penggantian string dan untuk membuat string multibaris. Fitur canggih lainnya yang mereka bawa adalah template bertag. Template Bertag 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 string template biasa. Pada dasarnya, ini adalah jenis panggilan fungsi khusus: "desugars" di atas menjadi

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

Perhatikan bagaimana argumen ke-(n + 1) sesuai dengan penggantian yang terjadi antara entri ke-n dan ke-(n + 1) dalam array string. Hal ini dapat berguna untuk berbagai hal, tetapi salah satu yang paling mudah adalah escape otomatis dari variabel yang diinterpolasi.

Misalnya, Anda dapat menulis fungsi escape HTML sehingga..

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

menampilkan string dengan variabel yang sesuai yang diganti, tetapi dengan semua karakter yang tidak aman untuk HTML diganti. Mari kita lakukan. Fungsi escape HTML kita akan menggunakan dua argumen: nama pengguna dan komentar. Keduanya dapat berisi karakter HTML yang tidak aman (yaitu ', ", <, >, dan &). Misalnya, jika nama pengguna adalah "Domenic Denicola" dan komentarnya adalah "& adalah tag yang menyenangkan", kita harus menampilkan:

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

Dengan demikian, solusi template bertag kami 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"

Kemungkinan penggunaan lainnya mencakup escape otomatis, pemformatan, pelokalan, dan secara umum, penggantian 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 ada di Chrome 41 beta+, Pratinjau Teknologi IE, Firefox 35+, dan io.js. Secara praktis, jika Anda ingin menggunakannya dalam produksi saat ini, keduanya didukung di Transpiler ES6 utama, termasuk Traceur dan 6to5. Lihat contoh Template String kami di repo contoh Chrome jika Anda ingin mencobanya. Anda mungkin juga tertarik dengan Ekuivalen ES6 di ES5, yang menunjukkan cara mendapatkan beberapa fitur Template String yang lebih mudah menggunakan ES5 saat ini.

String Template menghadirkan banyak kemampuan penting ke JavaScript. Hal 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 mereka bawa adalah template bertag - fitur penting untuk menulis DSL tersebut. Fungsi ini menerima bagian-bagian String Template sebagai argumen, lalu Anda dapat memutuskan cara menggunakan string dan penggantian untuk menentukan output akhir string.

Bacaan Lebih Lanjut