Как я могу сделать интерполяцию строк в JavaScript? - PullRequest
420 голосов
/ 11 сентября 2009

Рассмотрим этот код:

var age = 3;

console.log("I'm " + age + " years old!");

Есть ли другие способы вставить значение переменной в строку, кроме конкатенации строк?

Ответы [ 17 ]

358 голосов
/ 14 марта 2016

Начиная с ES6, вы можете использовать шаблонные литералы :

let age = 3
console.log(`I'm ${age} years old!`)

P.S. Обратите внимание на использование обратных галочек: ``.

220 голосов
/ 20 июля 2014

ТЛ; др

Используйте строковые литералы шаблона ECMAScript 2015, если применимо.

Объяснение

Нет прямого способа сделать это, согласно спецификациям ECMAScript 5, но ECMAScript 6 имеет шаблонные строки , которые также были известны как квази-литералы во время составления проекта спекуляция Используйте их так:

> var n = 42;
undefined
> `foo${n}bar`
'foo42bar'

Вы можете использовать любое допустимое выражение JavaScript внутри {}. Например:

> `foo${{name: 'Google'}.name}bar`
'fooGooglebar'
> `foo${1 + 3}bar`
'foo4bar'

Другая важная вещь - вам больше не нужно беспокоиться о многострочных строках. Вы можете написать их просто как

> `foo
...     bar`
'foo\n    bar'

Примечание: Я использовал io.js v2.4.0 для оценки всех строк шаблона, показанных выше. Вы также можете использовать последнюю версию Chrome для тестирования приведенных выше примеров.

Примечание: ES6 Спецификации в настоящее время завершены , но еще не реализованы во всех основных браузерах.
Согласно страницам Mozilla Developer Network , это будет реализовано для базовой поддержки, начиная со следующих версий: Firefox 34, Chrome 41, Internet Explorer 12. Если вы Opera, Safari, или пользователь Internet Explorer, и ему любопытно узнать об этом этот тестовый стенд можно использовать, чтобы поиграть, пока все не получат поддержку.

186 голосов
/ 11 сентября 2009

Исправление Дугласа Крокфорда JavaScript включает функцию String.prototype.supplant. Он короткий, знакомый и простой в использовании:

String.prototype.supplant = function (o) {
    return this.replace(/{([^{}]*)}/g,
        function (a, b) {
            var r = o[b];
            return typeof r === 'string' || typeof r === 'number' ? r : a;
        }
    );
};

// Usage:
alert("I'm {age} years old!".supplant({ age: 29 }));
alert("The {a} says {n}, {n}, {n}!".supplant({ a: 'cow', n: 'moo' }));

Если вы не хотите изменять прототип String, вы всегда можете адаптировать его, чтобы он был автономным, или поместил его в какое-то другое пространство имен или что-то еще.

49 голосов
/ 19 октября 2012

Предостережение: избегайте любой системы шаблонов, которая не позволяет вам избежать своих собственных разделителей. Например, не было бы возможности вывести следующее с использованием метода supplant(), упомянутого здесь.

"Мне 3 года, благодаря моей переменной {age}."

Простая интерполяция может работать для небольших автономных скриптов, но часто сопровождается этим недостатком дизайна, который ограничивает любое серьезное использование. Я искренне предпочитаю шаблоны DOM, такие как:

<div> I am <span id="age"></span> years old!</div>

И использовать манипуляции jQuery: $('#age').text(3)

С другой стороны, если вы просто устали от конкатенации строк, всегда есть альтернативный синтаксис:

var age = 3;
var str = ["I'm only", age, "years old"].join(" ");
22 голосов
/ 11 сентября 2009

Попробуйте sprintf . Например:

vsprintf('The first 4 letters of the english alphabet are: %s, %s, %s and %s', ['a', 'b', 'c', 'd']);
21 голосов
/ 11 сентября 2009

Вы можете использовать Система шаблонов прототипа , если вам действительно хочется использовать кувалду для того, чтобы сломать орех

var template = new Template("I'm #{age} years old!");
alert(template.evaluate({age: 21}));
15 голосов
/ 03 февраля 2016

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

// JavaScript
var stringValue = 'Hello, my name is {name}. You {action} my {relation}.'
    .replace(/{name}/g    ,'Indigo Montoya')
    .replace(/{action}/g  ,'killed')
    .replace(/{relation}/g,'father')
    ;

Хотя это не особенно эффективно, я нахожу это читабельным. Он всегда работает и всегда доступен:

' VBScript
dim template = "Hello, my name is {name}. You {action} my {relation}."
dim stringvalue = template
stringValue = replace(stringvalue, "{name}"    ,"Luke Skywalker")     
stringValue = replace(stringvalue, "{relation}","Father")     
stringValue = replace(stringvalue, "{action}"  ,"are")

ВСЕГДА

* COBOL
INSPECT stringvalue REPLACING FIRST '{name}'     BY 'Grendel'
INSPECT stringvalue REPLACING FIRST '{relation}' BY 'Mother'
INSPECT stringvalue REPLACING FIRST '{action}'   BY 'did unspeakable things to'
9 голосов
/ 22 марта 2016

Вы можете легко сделать это с помощью ES6 template string и перенести на ES5 с помощью любого доступного транспилара, такого как babel.

const age = 3;

console.log(`I'm ${age} years old!`);

http://www.es6fiddle.net/im3c3euc/

6 голосов
/ 20 июля 2014

Вот решение, которое требует от вас предоставить объекту значения. Если вы не предоставите объект в качестве параметра, он по умолчанию будет использовать глобальные переменные. Но лучше придерживаться параметра, это намного чище.

String.prototype.interpolate = function(props) {
    return this.replace(/\{(\w+)\}/g, function(match, expr) {
        return (props || window)[expr];
    });
};

// Test:

// Using the parameter (advised approach)
document.getElementById("resultA").innerText = "Eruption 1: {eruption1}".interpolate({ eruption1: 112 });

// Using the global scope
var eruption2 = 116;
document.getElementById("resultB").innerText = "Eruption 2: {eruption2}".interpolate();
<div id="resultA"></div><div id="resultB"></div>
6 голосов
/ 16 февраля 2013

Попробуйте Киви , легкий модуль JavaScript для интерполяции строк.

Вы можете сделать

Kiwi.compose("I'm % years old!", [age]);

или

Kiwi.compose("I'm %{age} years old!", {"age" : age});
...