У меня есть строка, которая содержит шаблонные литералы, но не является литералом шаблона из-за его динамического построения. Я хотел бы преобразовать его в шаблон "literal", не делая eval()
:
// this is dynamically created by an algo:
const vars = '${var1} ${var2}';
const str = 'the result is ' + vars;
// this works, but it nasty:
eval('result = '' + str + ''');
Я ищу доступ к внутреннему построителю шаблонов в духе класса RegExp, который можно использовать вместо стандартных реляционных слэшей регулярного выражения //
:
const myRegex = '^(\d+)$';
new RegExp(myRegex);
Таким образом я мог бы сделать:
const myStr = 'I want to be ${foo}';
const foo = 99;
const lit = new TemplateLiteral(myStr);
console.log( lit.run() ); // I want to be 99
Вы не можете "построить литерал". Это противоречие в терминах. Литерал - это синтаксис исходного кода, который компилируется в значение.
new RegExp(...)
создает новый объект regexp, но не литерал регулярного выражения. Регламент REGExp - это когда вы буквально пишете /.../
.
Точно так же строковый литерал буквально только тогда, когда вы пишете '...'
, "..."
или '...'
в коде. Вы можете построить строку - как правило, используя конкатенацию, но нет возможности построить строковый литерал.
EDIT: Быстрая и грязная:
function makeTemplate(template) {
return new Function("return '" + template + "'");
}
const myStr = 'I want to be ${foo}';
const foo = 99;
const template = makeTemplate(myStr);
console.log(template());
// I want to be 99
Однако, в то время как new Function
всегда лучше, чем eval
, применяются обычные отказы в выполнении ненадежных строк.
Для более безопасной альтернативы см. Mustache.js или Pug.js (а не Pod, как я сказал в комментарии, извините), как ведущие библиотеки шаблонов JavaScript.
RegExp
. Как только я построю объект шаблона, я вызову run()
. Я отредактирую вопрос для ясности.
Ключевая проблема здесь заключается в том, что у вас есть в вашем комментарии в первом блоке кода:
это динамически создается алгоритмом
Если шаблон создан по алгоритму, ваши варианты:
eval
или одного из его кузенов (возможно, new Function
)Динамические шаблоны шаблонов нельзя создавать динамически. Это литералы. :-)
Если бы мы знали больше о вашем алгоритме, мы могли бы помочь вам лучше. Например, вы могли бы создать алгоритм для создания функции, а затем вызвать эту функцию с информацией, которая может понадобиться:
function getVarsFormatter(var1First) {
if (var1First) {
return (var1, var2) => '${var1} ${var2}';
} else {
return (var1, var2) => '${var2} ${var1}';
}
}
затем
const formatter = getVarsFormatter(flag);
const result = formatter("this is var1", "this is var2");
Живой пример:
function getVarsFormatter(var1First) {
if (var1First) {
return (var1, var2) => '${var1} ${var2}';
} else {
return (var1, var2) => '${var2} ${var1}';
}
}
for (let n = 0; n < 6; ++n) {
const formatter = getVarsFormatter(Math.random() < 0.5);
const result = formatter("this is var1", "this is var2");
console.log(result);
}
new Function
двоюродного брата eval
.