当前位置: 首页 > 知识库问答 >
问题:

ES6模板文字可以在运行时替换(或重用)吗?

易弘阔
2023-03-14

TL;dr:有可能制作一个可重复使用的模板文字吗?

我一直在尝试使用模板文字,但我想我只是不明白,现在我很沮丧。我的意思是,我想我明白了,但“它”不应该是它的工作方式,或者它应该如何得到。它应该会有所不同。

我看到的所有示例(甚至标记的模板)都要求在声明时而不是运行时进行“替换”,这对我来说对模板来说是完全无用的。也许我疯了,但对我来说,“模板”是一个文档,它包含在使用时被替换的标记,而不是在创建时被替换,否则它只是一个文档(即字符串)。模板与标记一起存储为标记

每个人都举了一个可怕的例子,类似于:

var a = 'asd';
return `Worthless ${a}!`

这很好,但如果我已经知道a,我只需要返回“无价值的asd”返回“有价值的”a。这有什么意义?认真地好吧,重点是懒惰;更少的优点,更容易阅读。太棒了但这不是模板!不是IMHO。MHO才是最重要的!问题是,IMHO在声明模板时会对其进行求值,因此,如果你这样做了,IMHO:

var tpl = `My ${expletive} template`;
function go() { return tpl; }
go(); // SPACE-TIME ENDS!

由于未声明咒骂,因此它会输出类似于“我的未定义模板”的内容。超。实际上,至少在 Chrome 中,我什至无法声明模板;它抛出错误,因为未定义咒骂。我需要的是能够在声明模板后进行替换:

var tpl = `My ${expletive} template`;
function go() { return tpl; }
var expletive = 'great';
go(); // My great template

然而,我不明白这怎么可能,因为这些不是真正的模板。即使你说我应该使用标签,不,它们不起作用:

> explete = function(a,b) { console.log(a); console.log(b); }
< function (a,b) { console.log(a); console.log(b); }
> var tpl = explete`My ${expletive} template`
< VM2323:2 Uncaught ReferenceError: expletive is not defined...

这一切都让我相信模板文字被严重错误地命名,应该被称为它们真正的样子: herdocs。我想“文字”部分应该给我提供了线索(比如,不可变的)?

我错过了什么吗?有没有一种(好的)方法可以使可重用模板文字化?

我给你,可重用的模板文字:

> function out(t) { console.log(eval(t)); }
  var template = `\`This is
  my \${expletive} reusable
  template!\``;
  out(template);
  var expletive = 'curious';
  out(template);
  var expletive = 'AMAZING';
  out(template);
< This is
  my undefined reusable
  template!
  This is
  my curious reusable
  template!
  This is
  my AMAZING reusable
  template!

这是一个天真的“助手”功能...

function t(t) { return '`'+t.replace('{','${')+'`'; }
var template = t(`This is
my {expletive} reusable
template!`);

...让它“更好”。

我倾向于称它们为模板古特拉尔,因为它们产生曲折的感觉的区域。


共有3个答案

万俟皓
2023-03-14

可能最干净的方法是使用箭头函数(因为在这一点上,我们已经在使用ES6)

var reusable = () => `This ${object} was created by ${creator}`;

var object = "template string", creator = "a function";
console.log (reusable()); // "This template string was created by a function"

object = "example", creator = "me";
console.log (reusable()); // "This example was created by me"

...对于标记的模板文字:

reusable = () => myTag`The ${noun} go ${verb} and `;

var noun = "wheels on the bus", verb = "round";
var myTag = function (strings, noun, verb) {
    return strings[0] + noun + strings[1] + verb + strings[2] + verb;
};
console.log (reusable()); // "The wheels on the bus go round and round"

noun = "racecars", verb = "fast";
myTag = function (strings, noun, verb) {
    return strings[0] + noun + strings[1] + verb;
};
console.log (reusable()); // "The racecars go fast"

这还避免了使用eval()Function(),这可能会导致编译器出现问题并导致大量速度减慢。

公羊渝
2023-03-14

您可以将模板字符串放在函数中:

function reusable(a, b) {
  return `a is ${a} and b is ${b}`;
}

您可以使用标记模板做同样的事情:

function reusable(strings) {
  return function(... vals) {
    return strings.map(function(s, i) {
      return `${s}${vals[i] || ""}`;
    }).join("");
  };
}

var tagged = reusable`a is ${0} and b is ${1}`; // dummy "parameters"
console.log(tagged("hello", "world"));
// prints "a is hello b is world"
console.log(tagged("mars", "jupiter"));
// prints "a is mars b is jupiter"

这个想法是让模板解析器从变量“槽”中拆分出常量字符串,然后返回一个函数,每次都根据一组新值将其重新修补在一起。

袁运锋
2023-03-14

为了使这些文字像其他模板引擎一样工作,需要有一个中间形式。

执行此操作的最佳方法是使用函数构造函数

const templateString = "Hello ${this.name}!";
const templateVars = {
    name: "world"    
}

const fillTemplate = function(templateString, templateVars){
    return new Function("return `"+templateString +"`;").call(templateVars);
}

console.log(fillTemplate(templateString, templateVars));

与其他模板引擎一样,您可以从其他位置(如文件)获取该字符串。

使用这种方法可能会出现一些问题(例如,模板标签会更难添加)。因为后期的插值,你也不能有内联的JavaScript逻辑。这也可以通过一些思考来弥补。

 类似资料:
  • 主要内容:1.多行字符串,2.字符串插值,3.标记模板,4.原始字符串,5.String.fromCodePoint()模板文字是ECMAScript 2015/ES6中引入的新功能。它提供了创建多行字符串和执行字符串插值的简便方法。模板文字是字符串文字,并允许嵌入表达式。 在ES6之前,模板文字被称为模板字符串。 与字符串中的引号不同,模板文字用反引号()字符(QWERTY键盘中ESC键下方的键)括起来。 模板文字可以包含占位符,由美元符号和大括号表示。在反引号内,如果要使用表达式,则可以将该

  • 问题内容: 我正在使用新的ES6模板文字功能,想到的第一件事是JavaScript,因此我着手实现了一个原型: 但是,在将模板文字传递给我的原型方法之前,需要先对其进行评估。有什么方法可以编写上述代码以将结果推迟到动态创建元素之后? 问题答案: 我可以看到三种解决方法: 使用模板字符串,就像设计使用的那样,没有任何功能: // might make more sense with variable

  • 问题内容: 请考虑以下情形。我有一个带有bean的Spring应用程序上下文,该bean的属性应该是可配置的,认为或。可变的应用程序配置由单独的Bean管理,我们称之为。 管理员现在可以更改配置值,例如电子邮件地址或数据库URL,我想在运行时重新初始化配置的bean。 假设我不能只是简单地修改上述可配置bean的属性(例如,通过或构造函数注入创建),而必须重新创建bean本身。 关于如何实现这一点

  • 我正在玩新的ES6模板文字功能,我首先想到的是一个<code>字符串。为JavaScript格式化,所以我开始实现一个原型: ES6Fiddle 但是,模板文字在传递给我的原型方法之前会被评估。有没有什么方法可以编写上面的代码来将结果推迟到我动态创建元素之后?

  • 我工作在一个微服务应用程序,有多个服务。我正在使用docker-compose运行不同微服务的实例。我们为每个微服务创建一个映像。如果我改变了一个微服务的代码,我使用'docker-compose down',然后改变更新的微服务的版本,然后使用'docker-compose up'。我认为,应该有一种不使用'docker-compose down'和'docker-compose up'的方法在

  • 问题内容: 我想尝试使用模板文字,但它不起作用:它显示文字变量名称,而不是值。我正在使用Chromev50.0.2(和jQuery)。 例: 输出: 问题答案: JavaScript 模板文字 需要反引号,而不是直接引号。 您需要使用反引号(也称为“重音符”-您会在1键旁边找到)-而不是单引号-来创建模板文字。 反引号在许多编程语言中都很常见,但可能对JavaScript开发人员来说是新的。 范例