【问题标题】:Evaluating template literals dynamically动态评估模板文字
【发布时间】:2016-10-11 05:41:34
【问题描述】:

假设我有这样的模板文字:

const templateLiteral = `string text ${expression} string text`

我想将模板文字动态评估为完成的字符串。

function toFoo(templateLiteral){
   //returns "string text Foo string text"
   return templateLiteral.evaluate('Foo');  
}

function toBar(templateLiteral){
  //returns "string text Bar string text"
   return templateLiteral.evaluate('Bar');  
}

function toBaz(templateLiteral){
   //returns "string text Baz string text"
   return templateLiteral.evaluate('Baz');  
}

有没有办法用模板文字做这样的事情,还是我只是愚蠢? (template.evaluate() 是一个组合函数,但我正在寻找 JS 的那种功能!)。

【问题讨论】:

  • 听起来有点像一般的替换功能?
  • 但是......模板文字(像所有文字一样)不会在它出现的地方被评估,创建一个不知道它来自文字的字符串吗?
  • 如果它被包装在一个函数中,可能不会:)
  • 你可以找到关于模板字面量的有价值的信息 -indepth.dev/posts/1362/…

标签: javascript node.js


【解决方案1】:

我认为最好的方法是非常明显的,只需颠倒问题给出的情况即可。 您只需将模板文字包装在一个函数中,然后您将延迟评估,直到您传入所需的参数。就这么简单。

function evaluteTemplateLiteral(bar){
  return `foo ${bar} baz`;
}

现在如果你想变得更漂亮,你可以创建这个:

function evaluateGeneric(vals, fn){
   return fn.apply(null, vals);
}

你会像这样使用上面的:

evaluateGeneric(['brown','fox','cholo'], function(){
    return `the quick ${arguments[0]} fox ${arguments[1]}`;
});

【讨论】:

    【解决方案2】:

    标记的模板字符串可以在这种情况下提供帮助:

    function toFoo(strings, ...values) {
        console.log(strings[0]); // string text
        console.log(strings[1]); // string text
        console.log(values[0]);  // <your-passed-expression>
    
        // TODO: Do your manipulation
    }
    
    const val = toFoo`string text ${expression} string text`;
    

    strings 包含行的“正常”标记,values 是“变量”部分。请注意,您必须手动连接字符串。

    【讨论】:

    • 在您的示例中,strings 将是 ["string text ", " string text"],不是吗?
    【解决方案3】:

    我只会调用 eval,你在使用模板字符串时还是在评估代码

    【讨论】:

    • Eval 很有趣,但在某些情况下它可能会做一些坏事,因为它太通用了