24

What's the best way to do insert variables in a string in JavaScript? I'm guessing it's not this:

var coordinates = "x: " + x + ", y: " + y;

In Java, Strings are immutable and doing something like the above would unnecessarily create and throw away Strings. Ruby is similar and has a nice way of doing the above:

coordinates = "x: #{x}, y: #{y}"

Does something similar exist for JavaScript?

at.
  • 50,922
  • 104
  • 292
  • 461
  • Strings are immutable in JavaScript as well. The plus (concatenation) operator makes a new string from pieces of an old one. – Joe Simmons Sep 30 '13 at 22:31
  • Are we strictly talking vanilla here? Anyway underscores' templates do a pretty good job at that – raam86 Sep 30 '13 at 22:31
  • possible duplicate of [JavaScript equivalent to printf/string.format](http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format) – Naftali Sep 30 '13 at 22:33

4 Answers4

59

Introduced in ES6 as "template strings"

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

const name = "Nick"
const greeting = `Hello ${name}`  // "Hello Nick"
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
Nick Brady
  • 6,084
  • 1
  • 46
  • 71
  • 2
    Template strings were part of ES6 and that standard came around, and was implemented by browsers, well after 2013 when I posted this question. Nevertheless, you're correct and I will award you the check :) – at. Jun 13 '17 at 01:18
  • Any particular reason here for using back-ticks? Will single quotes work? – djangofan Jul 24 '19 at 16:16
  • 2
    No, You need to use backticks. It is how echmascript (javascript) knows how to inject variables into `${}` locations. A single tick would just signify a normal string and would be interpreted as such. – Nick Brady Jul 24 '19 at 17:37
3

https://www.npmjs.com/package/stringinject

https://github.com/tjcafferkey/stringinject

I created this function to do exactly this, it will allow you to pass in a string, and an object with keys that will replace placeholder values in the string with their values like below:

var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });

// My username is tjcafferkey on Github 
codebytom
  • 418
  • 4
  • 12
  • 1
    Pretty sure you accidentally transposed the variables. The way you have it written, I would expect it to set str to be "My username is Github on tjcafferkey" – Danny Jul 19 '17 at 16:10
  • Great spot. Got them the wrong way round on my example. – codebytom Jul 19 '17 at 16:20
2

That's fine in JavaScript. There is no good built-in equivalent of an sprintf or String.format, however, you can build your own.

Don't worry about the "unnecessary" string objects. That's definitely micro-optimization. Address it if and when you need that extra tiny bit of performance or memory optimization, but in distributed software, you probably don't.

Community
  • 1
  • 1
Nicole
  • 32,841
  • 11
  • 75
  • 101
  • 1
    Plus, if it is really common performance problem I would expect JS implementations to have it optimized. I know Java compiler does such optimization. – zch Sep 30 '13 at 22:33
1

If for some reason you are doing this many times per second and referencing the strings many times per call, you can always store the strings themselves as variables.

var preX = 'x: '
  , preY = 'y: '
  , coords
  ;
coords = preX + x + preY + y;

This of course should be supported by benchmarking/profiling, but creating many strings per frame is often a source of unnecessary garbage which can result in jank down the line.

Wyatt
  • 2,491
  • 15
  • 12
  • Is there really a JS interpreter that won't inline all of the raw strings? I feel like this might be *slower* on some browsers, since now the engines have to examine the `preX` (etc.) variables which could have changed, whereas it is impossible to change a string literal. – Platinum Azure Sep 30 '13 at 22:48
  • Agreed, I'd expect it to be slower. However, my case was specific to referring to the same string literal hundreds of times per frame (say in a visualization with many dynamically labeled points). The speed hit of optimized lookup (which will just be indexing into a given offset) will *likely* not outweigh string creation time for each literal. I imagine you are correct that the literals are optimized to some degree, but that varies browser by browser, making code that relies on that behavior implementation dependent. – Wyatt Sep 30 '13 at 23:40