web-dev-qa-db-fra.com

Comment interpoler des variables dans des chaînes en JavaScript, sans concaténation?

Je sais que dans PHP, nous pouvons faire quelque chose comme ceci:

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

Sortie: "I pity the foo"

Je me demandais si la même chose est possible en JavaScript également. Utilisation de variables à l'intérieur de chaînes sans concaténation - l'écriture est plus concise et élégante.

308
DMin

À partir de Firefox 34/Chrome 41/Safari 9/Microsoft Edge, vous pouvez utiliser une fonctionnalité ES2015/ES6 appelée littéraux de modèle et utiliser cette syntaxe:

`String text ${expression}`

Les littéraux de modèle sont entourés par le signe (``) (accent grave) au lieu de guillemets doubles ou simples.

Exemple:

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

Comment est-ce bien?

Bonus:

Il permet également des chaînes multi-lignes en javascript sans échapper, ce qui est excellent pour les modèles:

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

support du navigateur :

Cette syntaxe n'étant pas prise en charge par les anciens navigateurs (Internet Explorer et Safari <= 8), vous pouvez utiliser Babel pour transpiler votre code dans ES5 afin de garantir qu'il s'exécutera partout.


Note latérale:

À partir de IE8 +, vous pouvez utiliser le formatage de chaîne de base dans console.log:

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

Avant Firefox 34/Chrome 41/Safari 9/Microsoft Edge, Nope, cela n’était pas possible en javascript. Vous devrez recourir à:

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

Avant Firefox 34/Chrome 41/Safari 9/Microsoft Edge, no. Bien que vous puissiez essayer sprintf pour JavaScript pour vous rendre à mi-chemin:

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

vous pouvez le faire, mais ce n’est pas très général

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

Vous pouvez facilement écrire une fonction qui le fait intelligemment si vous aviez vraiment besoin de

27
Scott Evernden

Si vous aimez écrire CoffeeScript, vous pouvez faire:

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

CoffeeScript en réalité IS javascript, mais avec une syntaxe bien meilleure.

Pour un aperçu de CoffeeScript, vérifiez ceci guide du débutant .

9
bformet

Vous pouvez utiliser cette fonction javascript pour créer ce type de modèle. Pas besoin d'inclure une bibliothèque entière.

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

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

L'utilisation d'une fonction en tant qu'argument de la fonction String.replace () faisait partie de la spécification ECMAScript v3. Voir this SO answer pour plus de détails.

9
Eric Seastrand

Réponse complète, prête à être utilisée:

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

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

Appeler comme

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

Pour l'attacher à String.prototype:

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

Puis utilisez comme:

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

Si vous essayez de faire une interpolation pour micro-templates, j'aime bien Moustache.js pour cela.

4
Joe Martinez

J'ai écrit ce paquet npm stringinject https://www.npmjs.com/package/stringinject qui vous permet d'effectuer les opérations suivantes

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

qui remplacera {0} et {1} par les éléments du tableau et retournera la chaîne suivante

"this is a test string for stringInject"

ou vous pouvez remplacer les espaces réservés par des clés d'objet et des valeurs comme ceci:

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

"My username is tjcafferkey on Github" 
3
tjcafferkey

Ne voyez aucune bibliothèque externe mentionnée ici, mais Lodash a _.template(),

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

Si vous utilisez déjà la bibliothèque, cela vaut la peine de vérifier, et si vous n'utilisez pas Lodash, vous pouvez toujours choisir les méthodes de sélection à partir de npm npm install lodash.template pour vous permettre de réduire le temps système.

Forme la plus simple -

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

Il y a un tas d'options de configuration aussi -

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

J'ai trouvé les délimiteurs personnalisés les plus intéressants.

2