Come interpolare le variabili nelle stringhe in JavaScript, senza concatenazione?


409

So che in PHP possiamo fare qualcosa del genere:

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

Produzione: "I pity the foo"

Mi chiedevo se questa stessa cosa fosse possibile anche in JavaScript. L'uso di variabili all'interno di stringhe senza usare la concatenazione - sembra più conciso ed elegante da scrivere.

Risposte:


696

Puoi trarre vantaggio dai modelli letterali e utilizzare questa sintassi:

`String text ${expression}`

I letterali modello sono racchiusi tra il segno di spunta posteriore (``) (accento grave) anziché tra virgolette doppie o singole.

Questa funzione è stata introdotta in ES2015 (ES6).

Esempio

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

Quanto è pulito?

Bonus:

Consente anche stringhe multilinea in javascript senza escape, il che è ottimo per i template:

return `
    <div class="${foo}">
         ...
    </div>
`;

Supporto per il browser :

Poiché questa sintassi non è supportata dai browser più vecchi (principalmente Internet Explorer), potresti voler usare Babel / Webpack per traspilare il tuo codice in ES5 per assicurarti che funzionerà ovunque.


Nota a margine:

A partire da IE8 + è possibile utilizzare la formattazione di stringa di base all'interno console.log:

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

57
Non perdere il fatto che la stringa del modello è delimitata da segni di spunta posteriori (`) anziché dai normali caratteri di virgoletta. "${foo}"è letteralmente $ {foo} `${foo}`è quello che realmente vuoi
Hovis Biddle il

1
Inoltre ci sono molti transpiler che trasformano ES6 in ES5 per risolvere il problema di compatibilità!
Nick,

quando cambio valore a o b. console.log ( Fifteen is ${a + b}.); non è cambiato dinamicamente. mostra sempre Quindici è 15.
Dharan,

168

Prima di Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, no, questo non era possibile in JavaScript. Dovresti ricorrere a:

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

2
Presto sarà possibile in javascript (ES6) con Template Strings, vedere la mia risposta dettagliata di seguito.
bformet,

È possibile se ti piace scrivere CoffeeScript, che in realtà è javascript con una sintassi migliore.
bformet,

1
Grande urlo per i browser più vecchi :)
Kirsty Marks,

1
Compatisco l'UFAM !!! è fantastico
Adam Hughes, il


32

bene potresti farlo, ma non è particolarmente generale

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

Si potrebbe facilmente scrivere una funzione che lo fa in modo intelligente se proprio necessario


Abbastanza decente, in realtà.
Mr. B

1
Questa risposta è buona quando è necessario archiviare la stringa di modello nel database ed elaborarla su richiesta
Dima Escaroda

Bene, funziona bene. molto semplice ma non mi è venuto in mente.
Sam,

13

Risposta completa, pronta per essere utilizzata:

 var Strings = {
        create : (function() {
                var regexp = /{([^{]+)}/g;

                return function(str, o) {
                     return str.replace(regexp, function(ignore, key){
                           return (key = o[key]) == null ? '' : key;
                     });
                }
        })()
};

Chiama come

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

Per collegarlo a String.prototype:

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

Quindi utilizzare come:

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

10

È possibile utilizzare questa funzione JavaScript per eseguire questo tipo di modello. Non è necessario includere un'intera libreria.

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"
    }
);

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

L'uso di una funzione come argomento per la funzione String.replace () faceva parte della specifica ECMAScript v3. Vedi questa risposta SO per maggiori dettagli.


È efficiente?
mmm,

L'efficienza dipenderà in gran parte dal browser dell'utente, poiché questa soluzione delega il "sollevamento pesante" della corrispondenza del regex e della sostituzione delle stringhe con le funzioni native del browser. In ogni caso, dal momento che ciò sta accadendo sul lato browser, l'efficienza non è così grande. Se si desidera il modello sul lato server (per Node.JS o simili), è necessario utilizzare la soluzione letterale del modello ES6 descritta da @bformet, poiché è probabilmente più efficiente.
Eric Seastrand,

9

Se ti piace scrivere CoffeeScript potresti fare:

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

CoffeeScript è in realtà javascript, ma con una sintassi molto migliore.

Per una panoramica di CoffeeScript, consulta questa guida per principianti .



3

Ho scritto questo pacchetto npm stringinject https://www.npmjs.com/package/stringinject che ti permette di fare quanto segue

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

che sostituirà {0} e {1} con gli elementi dell'array e restituirà la seguente stringa

"this is a test string for stringInject"

oppure potresti sostituire i segnaposto con chiavi oggetto e valori in questo modo:

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

"My username is tjcafferkey on Github" 

3

Vorrei usare il back-tick ''.

let name1 = 'Geoffrey';
let msg1 = `Hello ${name1}`;
console.log(msg1); // 'Hello Geoffrey'

Ma se non sai name1quando crei msg1.

Ad esempio, se msg1proveniva da un'API.

Puoi usare :

let name2 = 'Geoffrey';
let msg2 = 'Hello ${name2}';
console.log(msg2); // 'Hello ${name2}'

const regexp = /\${([^{]+)}/g;
let result = msg2.replace(regexp, function(ignore, key){
    return eval(key);
});
console.log(result); // 'Hello Geoffrey'

Sostituirà ${name2}con il suo valore.


2

Non vedi le librerie esterne menzionate qui, ma Lodash ha _.template(),

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

Se stai già utilizzando la libreria, vale la pena dare un'occhiata e se non stai usando Lodash puoi sempre scegliere i metodi da npm in npm install lodash.templatemodo da poter ridurre le spese generali.

La forma più semplice -

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

Ci sono anche un sacco di opzioni di configurazione -

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

Ho trovato i delimitatori personalizzati più interessanti.


0

Crea un metodo simile a quello String.format()di Java

StringJoin=(s, r=[])=>{
  r.map((v,i)=>{
    s = s.replace('%'+(i+1),v)
  })
return s
}

uso

console.log(StringJoin('I can %1 a %2',['create','method'])) //output: 'I can create a method'

0

Citazione di pace del 2020:

Console.WriteLine("I {0} JavaScript!", ">:D<");

console.log(`I ${'>:D<'} C#`)

0

Usa semplicemente:

var util = require('util');

var value = 15;
var s = util.format("The variable value is: %s", value)

-1
String.prototype.interpole = function () {
    var c=0, txt=this;
    while (txt.search(/{var}/g) > 0){
        txt = txt.replace(/{var}/, arguments[c]);
        c++;
    }
    return txt;
}

uso:

var hello = "foo";
var my_string = "I pity the {var}".interpole(hello);
//resultado "I pity the foo"

-2

var hello = "foo";

var my_string ="I pity the";

console.log (my_string, ciao)


1
Questo non risponde alla domanda. È possibile disconnettere entrambe le stringhe in una riga, ma ciò non fornisce una nuova stringa contenente entrambe le stringhe, che è ciò che OP richiede.
Max Vollmer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.