动态评估模板字面量

14

假设我有如下的模板字面量:

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() 是一个虚构的函数,但我正在寻找类似于 JavaScript 的这种功能!)


有点像通用的替换函数,不是吗? - peteb
但是...一个模板字面量(像所有字面量一样)不会在它出现的点被评估,创建一个不知道它来自字面量的字符串吗? - nnnnnn
可能不会,如果它被包装在一个函数中 :) - Alexander Mills
您可以在以下链接中找到有关模板字面量的宝贵信息:https://indepth.dev/posts/1362/getting-started-with-modern-javascript-template-literals - Varvara Sandakova
4个回答

12

最好的方法非常明显,只需要反转问题中给出的情况。您只需要将模板字面量包装在一个函数中,然后您将延迟评估直到传递所需的参数。就是这么简单。

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]}`;
});

1

标记模板字符串可以在这种情况下有所帮助:

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"],对吗? - nnnnnn

0

我会直接调用 eval,因为使用模板字符串时,你本来就在评估代码。


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

0
可重复使用且简化的模板函数,具有动态值。

const contentTemplate = (template, dynamicValues, callback, selector) => {
  const regex = /{{(.*?)}}/g;
  const result = template.replace(regex, (match, captureKey) => { 
    return dynamicValues[captureKey] || '';
  })
  callback && callback(result, selector)
  return result
}

const content = 'Hello, My is {{name}}, age is {{age}} and Im from {{city}}';
const dynamicValues = {
  name: 'Amoos',
  age: 28,
  city: 'Paris'
}

const addContentFunction = ( tranformedContent, selector ) => {
  const app = document.querySelector(selector)
  app.innerHTML = tranformedContent ? tranformedContent : 'No content!'
}

contentTemplate(content, dynamicValues, addContentFunction, '#myId')
contentTemplate(content, {name: 'Rifat', age: 24, city: 'Berlin' }, addContentFunction, '.myClass')
<div id="myId"></div>
<hr />
<div class="myClass"></div>


我的回答更符合习惯用语,我认为使用TypeScript可以进行类型检查等操作。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接