Как интерполяция переменных в строках в JavaScript, без конкатенации?

Я знаю, что в PHP мы можем сделать что-то вроде этого:

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

выход: "I pity the foo"

мне было интересно, возможно ли то же самое и в JavaScript. Использование переменных внутри строк без использования конкатенации-это выглядит более лаконичным и элегантным для записи.

10 ответов


начиная с Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge вы можете использовать функцию ES2015 / ES6 под названием Шаблон Литералы и используйте следующий синтаксис:

`String text ${expression}`

литералы шаблонов заключаются в обратной кавычки (` `) (серьезный акцент) вместо двойных или одинарных кавычек.

пример:

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

насколько это аккуратно?

бонус:

Это также позволяет многострочные строки в javascript без экранирования, что отлично подходит для шаблонов:

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

поддержка браузеров:

поскольку этот синтаксис не поддерживается старыми браузерами (Internet Explorer и Safari Бабель чтобы транспилировать код в ES5, чтобы убедиться, что он будет работать везде.


Примечание:

начиная с IE8+ вы можете использовать обычную строку форматирование внутри console.log:

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

до Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, нет, это было невозможно в javascript. Вам придется прибегнуть к:

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

до Firefox 34 / Chrome 41 / Safari 9 / Microsoft Edge, нет. Хотя вы могли бы попробовать sprintf для JavaScript чтобы добраться до середины:

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

ну, вы могли бы это сделать, но это не esp general

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

вы можете легко написать функцию, которая делает это разумно, если вам действительно нужно


Если вы хотите написать CoffeeScript, вы можете сделать:

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

CoffeeScript на самом деле является javascript, но с гораздо лучшим синтаксисом.

для обзора CoffeeScript проверьте это для начинающих.


полный ответ, готовый к использованию:

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

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

называй как

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

прикрепить его к строке.прототип:

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

затем использовать как :

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

вы можете использовать эту функцию javascript для выполнения такого рода шаблонов. Нет необходимости включать целую библиотеку.

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

выход: "I would like to receive email updates from this store FOO BAR BAZ."

использование функции в качестве аргумента строки.функция replace () была частью спецификации ECMAScript v3. См.это так ответ для получения более подробной информации.


Если вы пытаетесь сделать интерполяцию для микротемпляции, мне нравится усы.js для этой цели.


Я написал этот пакет npm stringinject https://www.npmjs.com/package/stringinject что позволяет сделать следующее

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

который заменит {0} и {1} элементами массива и вернет следующую строку

"this is a test string for stringInject"

или вы можете заменить заполнители ключами объектов и значениями, например:

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

"My username is tjcafferkey on Github" 

не вижу никаких внешних библиотек, упомянутых здесь, но Lodash имеет _.template(),

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

если вы уже используете библиотеку, стоит проверить, и если вы не используете Lodash, вы всегда можете использовать методы cherry pick из npm npm install lodash.template таким образом, вы можете сократить накладные расходы.

простейшей форме -

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

есть куча параметров конфигурации также -

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

Я нашел пользовательские разделители самое интересное.