12/08/2018, 14:26

Javascript Template Literals

Giới thiệu Template Literals hay còn gọi là Template Strings là một cú pháp mới để khai báo String trong Javascript được giới thiệu trong ES2015/ES6. Nó cho phép chúng ta sử dụng multi-line string, sử dụng biến, biểu thức, hàm bên trong string mà không phải thông qua phép cộng string. Cú pháp ...

Giới thiệu

Template Literals hay còn gọi là Template Strings là một cú pháp mới để khai báo String trong Javascript được giới thiệu trong ES2015/ES6.

Nó cho phép chúng ta sử dụng multi-line string, sử dụng biến, biểu thức, hàm bên trong string mà không phải thông qua phép cộng string.

Cú pháp

var multiLine = `Tôi dang tay ôm nước vào lòng,
    Sông mở nước ôm tôi vào dạ`;
var cat = `Con mèo`;
var embededVar = `${cat} đang bay?`; // Con mèo đang bay?
var price = 500;
var embededEx = `1 cái kem giá ${price}đ => ${cat} mua 2 cái kem phải trả ${2 * price}đ`;

Viết theo cách cũ thì các bạn cũng biết rồi chứ, cộng nháy nháy cộng cộng nháy nháy cộng cộng... các kiểu cộng...

Thông thường chúng ta sử dụng dấu nháy đơn ' hoặc kép " để khai báo string. Đối với template literals thì chúng được thay thế bới dấu back-tick `, biến và biểu thức được đặt trong ${expression}. Dấu ` có thể được escape bằng dấu :

``` === '`' // true

Bên trong $() có thể là bất cứ biểu thức javascript nào.

// Function
var cat = 'Con mèo';
function catWork() { return 'trèo cây cau!?'; }
console.log(`${cat} đang ${catWork()}`);
// Other funciton
var cat = {
    name: 'Móm',
    work: function() {
        return 'trèo cây cau!?';
    }
};
console.log(`${cat.name.toUpperCase()} đang ${cat.work()}`);

Viết HTML template

var cat = {
    name: 'Mun',
    job: 'Hái cau',
    bio: 'Chơi là chính, ngủ là chủ yếu, việc thì bỏ bê',
    rating: 1,
    voice: function () {
        return 'mimi mimi';
    },
    tags: ['màu trắng', 'lùn', 'hơi nhác'],
};

var markup = `
    <div class="cat">
        <h2>${cat.name}</h2>
        <p class="job">${cat.job}</p>
        <p class="bio">${cat.bio}</p>
        <p class="star">${cat.rating}*</p>
        <p class="voice">${cat.voice()}</p>
        <p class="tags">
            ${cat.tags.map(tag => ` <span>${tag}</span>`)}
        </p>
    </div>
`;

Kết quả:

    <div class="cat">
        <h2>Mun</h2>
        <p class="job">Hái cau</p>
        <p class="bio">Chơi là chính, ngủ là chủ yếu, việc thì bỏ bê</p>
        <p class="star">1*</p>
        <p class="voice">mimi mimi</p>
        <p class="tags">
            <span>màu trắng</span>, <span>hơi nhác</span>, <span>lười</span>
        </p>
    </div>

Tagged template

Một tính năng nữa của Template Literals đó là Tagged Template. Tính năng này cho phép chúng ta truyền một template literals vào 1 hàm tag bằng cách viết tên hàm này trước dấu back-tick bắt đầu 1 template literal. Hàm tag này được dùng để xử lý chuỗi trước khi chúng được in ra hay gán vào 1 biến khác. VD:

var cat = 'Mèo meo';
var action = 'loanh quanh';
helperFunc`${cat} đi ${action}`;
// Tương đương với việc gọi hàm
helperFunc(["", " đi ", " trong sân."], cat, action);
// Hàm có dạng
function helperFunc(strings, expressionValue) {
    // strings => ["", " đi ", " trong sân."]
    // expressionValue => cat
}
// Hoặc
function helperFunc(strings, ...expressionValues) {
    // strings => ["", " đi ", " trong sân."]
    // expressionValues => [cat, action]
}

Ví dụ, sử dụng hàm tag để escape HTML các biến bên trong template string: https://developers.google.com/web/updates/2015/01/ES6-Template-Strings

// HTML Escape helper utility
var htmlUtils = (function () {
    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(strings, ...values) {
    var str = strings[0];
    for (var i = 1; i < strings.length; ++i) {
        str += htmlUtils.escape(values[i - 1]) + strings[i];
    }

    return str;
}

var cat = "Mốc";
var tag = "<ngu> & <lười>";
console.log(html`Con mèo <b>${cat}</b>: "${tag}"`);
// Con mèo <b>Mốc</b>: "&lt;ngu&gt; &amp; &lt;lười&gt;"

Browser support

  • Desktop

    Chrome Edge Firefox Internet Explorer Opera Safari
    41 (Yes) 34 No support 28 9
  • Mobile

    Chrome Android Firefox Mobile IE Mobile Opera Safari
    41 34 No support 28 9

Hầu hết các trình duyệt đã hỗ trợ viết template string (xem thêm). Ngoài ra bạn cũng có thể sử dụng BabelJS hoặc TypeScript để support các trình duyệt khác.

Tham khảo thêm

  • http://wesbos.com/javascript-template-strings/
  • https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals
  • http://exploringjs.com/es6/ch_template-literals.html
  • http://wesbos.com/template-strings-html/
  • https://github.com/addyosmani/es6-equivalents-in-es5#template-literals
  • https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
0