JavaScript: Tagged Template String

By Xah Lee. Date: . Last updated: .

New in JS2015.

First, see Template String .

There's a special notation to call a function, called tagged template string. The syntax is:

functionName`…`

When function is called this way, the function is fed one or more arguments based on the template string the `…`.

The first argument is a array, and each elements are literal segment of the template string. That is, the template string is split into parts, separated by the pattern ${}.

For example, `aa${3+4}bb` is separated into 2 parts, "aa" and "bb". The function will get ["aa","bb"] as first argument.

The rest arguments, are the embeded expressions of the template string. For example, in f`aa${33}bb${44}cc`, the function will get "33" as second argument, and "44" as 3rd argument. (they are evaluated.)

In the following example, we show what happens to the first argument.

// tagged template function calling.
// first arg is array, of literal parts of the template string

function f(x) { return x; };

console.log(
 f`a`
); // ['a']

console.log(
 f`a ${5} b`
); // ['a ', ' b']

console.log(
 f`a ${5}`
); // ['a ', '']


console.log(
 f`${5} b`
); // ['', ' b']

console.log(
 f`${5}`
); // ['', '']

In the following example, we show all received arguments.

// tagged template function call
// show args received

function f() { return arguments; };

console.log(
 f`a`
);
// prints
// { '0': [ 'a' ] }
// Because there is no embedded expression

console.log(
 f`a ${3}`
);
// prints
// { '0': [ 'a ', '' ], '1': 3 }

console.log(
 f`a ${3} b ${6}`
);
// prints
// { '0': [ 'a ', ' b ', '' ], '1': 3, '2': 6 }

console.log(
 f`a ${2+3} b`
);
// prints
// { '0': [ 'a ', ' b' ], '1': 5 }
// expression is evaluated

Recall that arguments Object is a builtin Array-Like Object that contains all received arguments.

Purpose of Tagged Template

Tagged template let you modify template in a flexible way.

instead of just printing a template string output = `…` you can modify it by adding a function output = f`…`.

Reconstruct Order

The original template string can be reconstructed by using the parts's indexes.

The literal parts can be accessed by arguments[0][i]. The first one is arguments[0][0]. The last one is arguments[0][arguments.length - 1].

The expression parts can be accessed by arguments[i]. The first one is arguments[1]. The last one is arguments[arguments.length - 1].

For each expression part arguments[i], there's always a literal string part arguments[0][i] following it (may be empty string).

// reconstruct template string
// showing order relation of literal parts and placeholder parts

function ff () {

    var result = arguments[0][0]; // first literal string part

    // go thru by expr index, starting from 1.
    for (var i = 1; i < arguments.length; i++) {
        result += arguments[i] + arguments[0][i];
    };

    return result;
};

console.log(
 `a ${1} b ${2} c ${3}`
); // a 1 b 2 c 3

console.log(
 ff`a ${1} b ${2} c ${3}`
); // a 1 b 2 c 3

console.log(
 `a ${1} b ${2} c ${3} d`
); // a 1 b 2 c 3 d

console.log(
 ff`a ${1} b ${2} c ${3} d`
); // a 1 b 2 c 3 d


// test degenerate cases

console.log(
 `a` === ff`a`
); // true

console.log(
 `${1}` === ff`${1}`
); // true

console.log(
 `a ${1}` === ff`a ${1}`
); // true

console.log(
 `${1} b` === ff`${1} b`
); // true

console.log(
 `a ${1}${2}` === ff`a ${1}${2}`
); // true

JavaScript String

BUY ΣJS JavaScript in Depth