我有一个字符串,其中包含模板文字变量,但由于它是动态构建的,因此不是模板文字。我想不做eval()
就将它转换成模板“ literal”:
// this is dynamically created by an algo:
const vars = '${var1} ${var2}';
const str = 'the result is ' + vars;
// this works, but it's nasty:
eval('result = `' + str + '`');
我正在寻求本着RegExp类的精神访问内部模板构建器的方法,该类可用于代替标准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
答案 0 :(得分:3)
您不能“构建文字”。这是一个矛盾。文字是源代码中的一种语法,可以编译为一个值。
new RegExp(...)
生成一个新的regexp对象,而不是一个regexp文字。 RegExp文字是您实际写/.../
的时候。
以相同的方式,仅当您在代码中编写'...'
,"..."
或`...`
时,字符串文字才是字面值。您可以构建 string -通常使用串联-但无法构建字符串 literal 。
编辑:快速又肮脏:
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模板库。
答案 1 :(得分:1)
这里的关键问题是您在第一个代码块中的注释内容:
这是由算法动态创建的
如果模板是由算法创建的,则您的选择是:
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);
}