Como interpolar variables ​​em strings em JavaScript, sem concatenação?

Eu sei em PHP podemos fazer algo assim:

$hello = "foo"; $my_string = "I pity the $hello"; 

Saída: "I pity the foo"

Eu queria saber se essa mesma coisa é possível em JavaScript também. Usando variables ​​dentro de strings sem usar concatenação – parece mais conciso e elegante para escrever.

A partir do Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, você pode usar um recurso do ES2015 / ES6 chamado Template Literals e usar esta syntax:

 `String text ${expression}` 

Os literais de gabarito são colocados por trás do caractere (“) (sotaque grave) em vez de aspas duplas ou simples.

Exemplo:

 var a = 5; var b = 10; console.log(`Fifteen is ${a + b}.`); // "Fifteen is 15. 

Quão bom é isso?

Bônus:

Ele também permite strings de várias linhas em javascript sem fugir, o que é ótimo para modelos:

 return ` 
...
`;

Suporte do navegador :

Como essa syntax não é suportada por navegadores mais antigos (Internet Explorer e Safari < = 8), talvez você queira usar o Babel para transpilar seu código para o ES5 para garantir que ele seja executado em todos os lugares.


Nota:

A partir do IE8 + você pode usar a formatação básica de strings dentro do console.log :

 console.log('%s is %d.', 'Fifteen', 15); // Fifteen is 15. 

Antes do Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, não, isso não era possível em javascript. Você teria que recorrer a:

 var hello = "foo"; var my_string = "I pity the " + hello; 

Antes do Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, não. Embora você possa tentar o sprintf para JavaScript ficar no meio do caminho:

 var hello = "foo"; var my_string = sprintf("I pity the %s", hello); 

bem, você poderia fazer isso, mas não é esp geral

 'I pity the $fool'.replace('$fool', 'fool') 

Você poderia facilmente escrever uma function que faz isso de forma inteligente se você realmente precisava

Se você gosta de escrever o CoffeeScript você pode fazer:

 hello = "foo" my_string = "I pity the #{hello}" 

CoffeeScript, na verdade, é javascript, mas com uma syntax muito melhor.

Para uma visão geral do CoffeeScript, consulte este guia para iniciantes .

Resposta completa, pronta para ser usada:

  var Strings = { create : (function() { var regexp = /{([^{]+)}/g; return function(str, o) { return str.replace(regexp, function(ignore, key){ return (key = o[key]) == null ? '' : key; }); } })() }; 

Ligue como

 Strings.create("My firstname is {first}, my last name is {last}", {first:'Neo', last:'Andersson'}); 

Para anexá-lo ao String.prototype:

 String.prototype.create = function(o) { return Strings.create(this, o); } 

Então use como:

 "My firstname is ${first}".create({first:'Neo'}); 

Você pode usar essa function de javascript para fazer esse tipo de modelo. Não há necessidade de include uma biblioteca inteira.

 function createStringFromTemplate(template, variables) { return template.replace(new RegExp("\{([^\{]+)\}", "g"), function(_unused, varName){ return variables[varName]; }); } createStringFromTemplate( "I would like to receive email updates from {list_name} {var1} {var2} {var3}.", { list_name : "this store", var1 : "FOO", var2 : "BAR", var3 : "BAZ" } ); 

Saída : "I would like to receive email updates from this store FOO BAR BAZ."

Usando uma function como um argumento para a function String.replace () fazia parte da especificação ECMAScript v3. Veja esta resposta para mais detalhes.

Se você está tentando fazer interpolação para microtemplating, eu gosto de Mustache.js para esse propósito.

Eu escrevi este string do pacote npm https://www.npmjs.com/package/stringinject que permite que você faça o seguinte

 var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]); 

que replaceá {0} e {1} pelos itens da matriz e retornará a seguinte string

 "this is a test string for stringInject" 

ou você pode replace espaços reservados por chaves de objects e valores como:

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

Não vejo nenhuma biblioteca externa mencionada aqui, mas Lodash tem _.template() ,

https://lodash.com/docs/4.17.10#template

Se você já está fazendo uso da biblioteca, vale a pena conferir, e se você não estiver usando o Lodash, você pode sempre selecionar methods a partir do npm npm install lodash.template para que você possa reduzir a sobrecarga.

Forma mais simples –

 var compiled = _.template('hello < %= user %>!'); compiled({ 'user': 'fred' }); // => 'hello fred!' 

Há um monte de opções de configuração também –

 _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; var compiled = _.template('hello {{ user }}!'); compiled({ 'user': 'mustache' }); // => 'hello mustache!' 

Eu encontrei delimitadores personalizados mais interessantes.