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


409

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

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

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

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

Ответы:


698

Вы можете воспользоваться шаблонными литералами и использовать этот синтаксис:

`String text ${expression}`

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

Эта функция была введена в ES2015 (ES6).

пример

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

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

Бонус:

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

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

Поддержка браузера :

Поскольку этот синтаксис не поддерживается старыми браузерами (в основном Internet Explorer), вы можете использовать Babel / Webpack для переноса вашего кода в ES5, чтобы он работал везде.


Примечание:

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

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

57
Не пропустите тот факт, что строка шаблона разделена обратными галочками (`) вместо обычных символов кавычек. "${foo}"буквально $ {foo} `${foo}`это то, что вы на самом деле хотите
Ховис Биддл

1
Также есть много транспортеров, чтобы превратить ES6 в ES5, чтобы исправить проблему совместимости!
Ник

когда я изменяю значение a или b. console.log ( Fifteen is ${a + b}.); не изменяется динамически. это всегда показывает, Пятнадцать - 15.
Дхаран

168

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

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

2
Скоро это станет возможным в javascript (ES6) со строками шаблонов, см. Мой подробный ответ ниже.
bformet

Это возможно, если вам нравится писать CoffeeScript, который на самом деле является JavaScript с лучшим синтаксисом.
bformet

1
Отличный крик для старых браузеров :)
Кирсти Маркс

1
Мне жаль FOO !!! это здорово
Адам Хьюз


32

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

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

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


Довольно прилично, на самом деле.
г-н Б

1
Этот ответ хорош, когда вам нужно сохранить строку шаблона в базе данных и обработать ее по требованию
Дима Эскарода

Хорошо, это работает хорошо. очень просто но не пришло в голову.
Сэм

13

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

 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:

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

Тогда используйте как:

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

10

Вы можете использовать эту функцию 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."

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


Это эффективно?
ммм

Эффективность будет в значительной степени зависеть от браузера пользователя, так как это решение делегирует «тяжелую работу» по сопоставлению регулярного выражения и выполнению замены строк в собственных функциях браузера. В любом случае, поскольку в любом случае это происходит на стороне браузера, эффективность не так уж важна. Если вы хотите использовать шаблоны на стороне сервера (для Node.JS и т. П.), Вы должны использовать шаблонное решение ES6, описанное @bformet, так как оно, вероятно, более эффективно.
Эрик Сеастранд

9

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

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

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

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



3

Я написал этот пакет 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" 

3

Я бы использовал обратную галочку ``.

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

Но если вы не знаете, name1когда вы создаете msg1.

Например, если msg1пришел из API.

Ты можешь использовать :

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'

Это заменит ${name2}его стоимость.


2

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

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

Если вы уже используете библиотеку, стоит проверить, и если вы не используете Lodash, вы всегда можете выбрать методы выбора из 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!'

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


0

Создать метод, похожий на String.format()Java

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

использование

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

0

Мирная цитата 2020 года:

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

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


-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, привет)


1
Это не отвечает на вопрос. Вы можете выйти из обеих строк в одну строку, но это не даст вам новую строку, содержащую обе строки, о чем просит OP.
Макс Воллмер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.