Es6 Template Literals VS. Concatenated Strings

ES6 template literals vs. concatenated strings

If you are using template literals only with placeholders (e.g. `Hello ${person.name}`) like in the question's example, then the result is the same as just concatenating strings. Subjectively it looks better and is easier to read, especially for multi-line strings or strings containing both ' and " since you don't have to escape those characters any more.

Readability is a great feature, but the most interesting thing about templates are Tagged template literals:

let person = {name: 'John Smith'}; 
let tag = (strArr, name) => strArr[0] + name.toUpperCase() + strArr[1];
tag `My name is ${person.name}!` // Output: My name is JOHN SMITH!

In the third line of this example, a function named tag is called. The content of the template string is split into multiple variables, that you can access in the arguments of the tag function: literal sections (in this example the value of strArr[0] is My name is and the value of strArr[1] is !) and substitutions (John Smith). The template literal will be evaluated to whatever the tag function returns.

The ECMAScript wiki lists some possible use cases, like automatically escaping or encoding input, or localization. You could create a tag function named msg that looks up the literal parts like My name is and substitutes them with translations into the current locale's language, for example into German:

console.log(msg`My name is ${person.name}.`) // Output: Mein Name ist John Smith.

The value returned by the tag function doesn't even have to be a string. You could create a tag function named $ which evaluates the string and uses it as a query selector to return a collection of DOM nodes, like in this example:

$`a.${className}[href=~'//${domain}/']`

Are ES6 template literals faster than string concatenation?

It seems for the moment string concatenation is faster: http://jsperf.com/es6-string-literals-vs-string-concatenation

ES6 with variable                     19,992,512    ±5.21%    78% slower
String concatenation with variable 89,791,408 ±2.15% fastest
ES6 with function 461,358 ±3.12% 99% slower
String concatenation with function 503,255 ±1.77% 99% slower

I tested was run on Chrome 43.0.2334.0 canary (64-bit), which is using V8 4.3.31, with the #enable-javascript-harmony flag enabled.

For reference, the latest version on Node.js (0.12.0 at the time of writing) is using V8 3.28.73: https://raw.githubusercontent.com/joyent/node/master/ChangeLog

I'm sure all the possible performance optimizations that could be applied have not been applied yet, so it would be reasonable to expect performance to get better as ES6 gets closer to finalization and these features get migrated to the stable branch.


Edit: Thanks for the comments @user1329482, @icl7126, Nicolai Borisik, and FesterCluck. Now that about 2 years have passed since this question was asked, ES6 browser support has greatly increased, and a good amount of performance optimization has taken place. Here are some updates.

Edit: (February 2020) Updated Chrome result based on @JorgeFuentesGonzález comments and subsequent confirmation.

In Chrome (as of 59.0.3035), ES6 string literals are faster:

ES6 with variable                     48,161,401       ±1.07%    fastest
String concatenation with variable 27,046,298 ±0.48% 44% slower
ES6 with function 820,441 ±1.10% 98% slower
String concatenation with function 807,088 ±1.08% 98% slower

Update: In Chrome (as of 79.0.3945), String concatenation is faster... See comments.

In Firefox (as of 57.0.0), ES6 string literals are faster:

ES6 with variable                     1,924,610,984    ±0.50%    fastest
String concatenation with variable 1,876,993,458 ±0.79% 3% slower
ES6 with function 539,762 ±5.04% 100% slower
String concatenation with function 546,030 ±5.88% 100% slower

In Safari (as of 11.0.2), it depends:

ES6 with variable                     1,382,752,744    ±0.71%    fastest
String concatenation with variable 1,355,512,037 ±0.70% 2% slower
ES6 with function 876,516 ±1.01% 100% slower
String concatenation with function 883,370 ±0.79% 100% slower

When using a typecast string, ES6 string literals are faster. However, when calling a function from the literal, string concatenation is faster in this example.

If you really want to go deep and need to squeeze every drop of performance out of Safari, I would suggest setting up tests that see if/how incorrectly typed variables and multiple references within a literal effect performance.

Equality of ES6 Template Literal VS concatenated string

You need a value that serializes to a different value every time it's converted to a string.

const x = {
[Symbol.toPrimitive]: (y => () => y++)(0),
};

console.log(`${x}` !== '' + x);

Why are string templates preferred to string concatenation now?

Depends on the string in question. By popular opinion this:

`Hello ${name}! It's a pleasure to greet you.`

is more readable than

'Hello ' + name + '! It\'s a pleasure to greet you.'

If there are no variables or single quotes then the difference is negligible.

Problem concatenating strings using JavaScript template literals

I realize I could have made a much bigger sql statement as well as concatenating bigger chunks of code and that would have made the problem more clear. Thanks to @CertainPerformance and @Phil for the ideas.

Here is what I was really looking for that solves my bigger problem and still keeps me safe I'm pretty sure.

    const orderByAsc = Prisma.sql`ORDER BY ASC`;
const orderByDesc = Prisma.sql`ORDER BY DESC`;
const result =
await prisma.$queryRaw`SELECT * FROM User WHERE active = ${activeSetting} ${
orderBy === 'ASC' ? orderByAsc : orderByDesc
}`;

And it also let's me put expressions in my sub clauses if need be.

Can we use JS concat() inside Template literals (Template strings)?

Two answers for you:

  1. The content of a substitution (${...}) can be any expression. It's fine to do method calls there.

  2. concat seems like an odd choice in that particular case, since there's no need for it. For that reason, from a style perspective, I'd use the first version. But it's a style thing, and you can use concat if you like. Note VLAZ's point that once you've done that, the whole expression is already producing the string you want and you have no need of a template literal at all.

So I'd either use your original:

a = {
link: {
pathname: `${url.split('?')[0]}${userId}/items?userType=${userId}}`
},
};

or if you prefer concat:

a = {
link: {
pathname: url
.split('?')[0]
.concat(`${userId}/items?userType=${userId}`)},
},
};

typescript asking for template literal

You can see the template literals in MDN, and these are the prefered style in ES6.

In your case it would become the following:

const content = `${senderDisplay}, ${moment(timestamp).format('YY/MM/DD')} at ${moment(timestamp).format('h:mm A')}`;

Important differences:

  • Starts and ends with a backtick

  • Supports multiline strings

  • Expressions are interpolated with ${expression}

What are the limitations of using backtick enclosed string with variables in it in Javascript

Really you’re talking about two separate things: concatenation of strings and ES6 template literals.

You already understand string concatenation, but template literals come with many other features, like tagged templates.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates

The one downside to template literals is that you may be writing for an older browser that doesn’t support them: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Browser_compatibility



Related Topics



Leave a reply



Submit