Як інтерполювати змінні в рядки в JavaScript, без конкатенації?


408

Я знаю, що в PHP ми можемо зробити щось подібне:

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

Вихід: "I pity the foo"

Мені було цікаво, чи можливо те саме, що можливо і в JavaScript. Використання змінних всередині рядків без використання конкатенації - писати виглядає більш стисло та елегантно.

Відповіді:


695

Ви можете скористатися літературними шаблонами та використовувати цей синтаксис:

`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.

56
Не пропустіть той факт, що рядок шаблону розмежовано зворотними кліщами (`) замість звичайних символів цитати. "${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
Чудовий крик для старших браузерів :)
Kirsty Marks

1
Шкодую ФОО !!! це чудово
Адам Хьюз


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. Дивіться цю відповідь ТА для отримання більш детальної інформації.


Це ефективно?
ммм

Ефективність буде значною мірою залежати від браузера користувача, оскільки це рішення делегує "важкий підйом" відповідності регулярному вираженню та здійснення заміни рядків на початкові функції браузера. У будь-якому випадку, оскільки це так чи інакше відбувається на стороні браузера, ефективність не викликає такого великого занепокоєння. Якщо ви хочете базувати шаблони на стороні сервера (для Node.JS тощо), вам слід скористатись літеральним рішенням шаблону ES6, описаним @bformet, оскільки це, ймовірно, більш ефективно.
Eric Seastrand

9

Якщо ви хочете написати CoffeeScript, ви можете зробити:

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

CoffeeScript насправді є JavaScript, але з набагато кращим синтаксисом.

Для огляду CoffeeScript ознайомтеся з цим посібником для початківців .



3

Я написав цей пакет npm stringinjeinje 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

Якщо ви вже використовуєте бібліотеку, варто перевірити її, і якщо ви не використовуєте Лодаш, ви завжди можете вибирати методи вишні з 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
Це не відповідає на запитання. Ви можете вийти з обох рядків в одному рядку, але це не дає вам нову рядок, що містить обидва рядки, і це те, про що вимагає ОП.
Макс Волмер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.