18

i am tired of writing this:

string_needed="prefix....." + topic + "suffix...." + name + "testing";

i would think someone might have done something about this by now ;)

Phrogz
  • 296,393
  • 112
  • 651
  • 745
meow
  • 27,476
  • 33
  • 116
  • 177
  • Better make a shortcut for it then, this syntax won't go anywhere for a while. ;) The best you could do is something like a `sprintf` function, but that won't make things any shorter. – deceze Jan 20 '11 at 03:24
  • 1
    See the top-rated answer in the duplicate question. – Phrogz Jan 20 '11 at 04:56
  • 1
    ECMAscript 6 has template strings... so yes, in the future you will be able to do \`string text ${expression} string text\`: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings – Ajedi32 Feb 05 '15 at 15:52

5 Answers5

18

ES6 Update:

ES6 added template strings, which use backticks (`) instead of single or double quotes. In a template string, you can use the ${} syntax to add expressions. Using your example, it would be:

string_needed = `prefix.....${topic}suffix....${name}testing`

Original answer:

Sorry :(

I like to take advantage of Array.join:

["prefix ....", topic, "suffix....", name, "testing"].join("")

or use String.concat

String.concat("a", 2, "c")

or you could write your own concatenate function:

var concat = function(/* args */) {
    /*
     * Something involving a loop through arguments
     */
}

or use a 3rd-party sprintf function, such as http://www.diveintojavascript.com/projects/javascript-sprintf

erjiang
  • 44,417
  • 10
  • 64
  • 100
  • +1 for Array.join. Fastest method of doing this that you'll find (it's also much faster than raw string concatenation). – Reid Jan 20 '11 at 03:29
  • 2
    @Reid may i suggest this? http://blogs.sitepoint.com/2010/09/14/javascript-fast-string-concatenation/ ;) – Couto Jan 20 '11 at 04:09
  • Was just gonna say... Despite this technique getting a lot of attention, Array#join is *not* faster than string concatenation in many cases. – Jimmy Jan 20 '11 at 06:00
  • also one of a problem with array join approach is that it is hard it translate if you care about i18n. It's much easier to translate string like "I played %s with %i people." than "I played ", " with " and " people.". – katsuya Feb 26 '13 at 07:22
  • 1
    [`+` is faster than either join or concat](http://jsperf.com/concat-vs-plus-vs-join). @Couto dead link. – Jared Beck Jul 24 '13 at 16:15
10

You could consider using coffeescript to write the code (which has interpolation like Ruby ie #{foo}).

It 'compiles' down to javascript - so you will end up with javascript like what you've written, but without the need to write/maintain the +++ code you're tired of

I realize that asking you to consider another language is on the edge of being a valid answer or not but considering the way coffeescript works, and that one of your tags is Ruby, I'm hoping it'll pass.

PandaWood
  • 8,086
  • 9
  • 49
  • 54
7

As a Javascript curiosity, you can implement something that basically does Ruby-like interpolation:

sub = function(str) {
  return str.replace(/#\{(.*?)\}/g,
    function(whole, expr) {
      return eval(expr)
    })
}

js> y = "world!"
world!
js> sub("Hello #{y}")
Hello world!
js> sub("1 + 1 = #{1 + 1}")
1 + 1 = 2

Using it on anything but string literals is asking for trouble, and it's probably quite slow anyways (although I haven't measured). Just thought I'd let you know.

erjiang
  • 44,417
  • 10
  • 64
  • 100
1

Direct answer: No javascript doesn't support string interpolation.

The only way is to implement it yourself or use a third party lib who does it for you.

EDIT

As Marcos added in comments theres a proposal for ECMAScript 6 (Harmony), so we can have proper string interpolation:

var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

Please see more information here.

Paulo Fidalgo
  • 21,709
  • 7
  • 99
  • 115
  • 2
    This has changed. There is now a better way: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings Bringing in 2015 to JS what many languages like Ruby and PHP have enjoyed already. Neither this question nor its SO "duplicate" are allowing newer answers....so sad. – Marcos Feb 05 '15 at 15:36
0

I just wrote this hacky function to do this. Usage is as follows:

interpolate("#{gimme}, #{shelter}", {gimme:'hello', shelter:'world'})
// returns "hello, world"

And the implementation:

interpolate = function(formatString, data) {
    var i, len,
        formatChar,
        prevFormatChar,
        prevPrevFormatChar;
    var prop, startIndex = -1, endIndex = -1,
        finalString = '';
    for (i = 0, len = formatString.length; i<len; ++i) {
        formatChar = formatString[i];
        prevFormatChar = i===0 ? '\0' : formatString[i-1],
        prevPrevFormatChar =  i<2 ? '\0' : formatString[i-2];

        if (formatChar === '{' && prevFormatChar === '#' && prevPrevFormatChar !== '\\' ) {
            startIndex = i;
        } else if (formatChar === '}' && prevFormatChar !== '\\' && startIndex !== -1) {
            endIndex = i;
            finalString += data[formatString.substring(startIndex+1, endIndex)];
            startIndex = -1;
            endIndex = -1;
        } else if (startIndex === -1 && startIndex === -1){
            if ( (formatChar !== '\\' && formatChar !== '#') || ( (formatChar === '\\' || formatChar === '#') && prevFormatChar === '\\') ) {
                finalString += formatChar;
            }
        }
    }
    return finalString;
};
ratbum
  • 1,030
  • 12
  • 29