是否可以创建一个模板字符串作为一个普通的字符串,

let a = "b:${b}";

然后把它转换成一个模板字符串,

let b = 10;
console.log(a.template()); // b:10

没有eval, new Function和其他动态代码生成的手段?


当前回答

因为我们正在重新发明一些东西,这将是javascript中的一个可爱的特性。

我使用eval(),这是不安全的,但javascript是不安全的。我承认我不擅长javascript,但我有一个需求,我需要一个答案,所以我做了一个。

我选择用@而不是$来风格化我的变量,特别是因为我想使用文字的多行特性,直到它准备好才计算。变量语法是@{optionalobject。optionalobjectn。variable_name}

我不是javascript专家,所以我很乐意听取改进建议,但是……

var prsLiteral, prsRegex = /\@\{(.*?)(?!\@\{)\}/g
for(i = 0; i < myResultSet.length; i++) {
    prsLiteral = rt.replace(prsRegex,function (match,varname) {
        return eval(varname + "[" + i + "]");
        // you could instead use return eval(varname) if you're not looping.
    })
    console.log(prsLiteral);
}

下面是一个非常简单的实现

myResultSet = {totalrecords: 2, 姓名:["Bob", "Stephanie"], 37岁的年龄:[22]}; rt = '我的名字是@{myResultSet。我是@{myResultSet.Age}。' var prsLiteral, prsRegex = /\@\{(.*?)(?!\@\{)\}/g . var prsLiteral, prsRegex = /\@\ For (i = 0;i < myResultSet.totalrecords;我+ +){ prsLiteral = rt.replace(prsRegex,函数(匹配,varname) { 返回eval(varname + "[" + I + "]"); //如果不循环,可以使用return eval(varname)。 }) console.log (prsLiteral); }

在我的实际实现中,我选择使用@{{variable}}。再来一组大括号。不太可能意外地遇到这种情况。的正则表达式 /\@\{\{(.*?)(?!\@\{\{)\}\}/ g

为了便于阅读

\@\{\{    # opening sequence, @{{ literally.
(.*?)     # capturing the variable name
          # ^ captures only until it reaches the closing sequence
(?!       # negative lookahead, making sure the following
          # ^ pattern is not found ahead of the current character
  \@\{\{  # same as opening sequence, if you change that, change this
)
\}\}      # closing sequence.

如果您对正则表达式没有经验,一个非常安全的规则是转义每个非字母数字字符,并且不要不必要地转义字母,因为许多转义字母对于几乎所有类型的正则表达式都具有特殊意义。

其他回答

我知道我来晚了,但你可以:

Const a = (b) => ' b:${b} '; 令b = 10; console.log (a (b));/ / b: 10

我提出了这个实现,它的工作就像一个魅力。

function interpolateTemplate(template: string, args: any): string {
  return Object.entries(args).reduce(
    (result, [arg, val]) => result.replace(`$\{${arg}}`, `${val}`),
    template,
  )
}

const template = 'This is an example: ${name}, ${age} ${email}'

console.log(interpolateTemplate(template,{name:'Med', age:'20', email:'example@abc.com'}))

如果在模板中没有找到arg,可能会引发错误

由于模板字符串必须动态地(在运行时)获得对b变量的引用,所以答案是:不,没有动态代码生成是不可能做到的。

但是,使用eval非常简单:

let tpl = eval('`'+a+'`');

你想要的是:

//从问题中引用的非工作代码 让b = 10; console.log (a.template ()); / / b: 10

与eval完全相同(就功能和安全而言):获取包含代码的字符串并执行该代码的能力;执行的代码还可以看到调用者环境中的局部变量。

在JS中,函数无法看到调用者中的局部变量,除非该函数是eval()。甚至Function()也做不到。


当您听说JavaScript中出现了所谓的“模板字符串”时,很自然地认为这是一个内置的模板库,就像Mustache一样。它不是。它主要是字符串插值和JS的多行字符串。不过,我认为这在一段时间内将是一个普遍的误解。:(

这样做(这样做):

让a = 'b:${this.b}' 令b = 10 函数template(templateString, templateVars) { 返回new函数('return " + templateString + ' ").call(templateVars) } 结果。textContent = template(a, {b}) < b id =结果> < / b >