ES6 模板文字可以在运行时替换(或重用)吗? [英] Can ES6 template literals be substituted at runtime (or reused)?

查看:18
本文介绍了ES6 模板文字可以在运行时替换(或重用)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl;dr:是否可以制作可重用的模板文字?

我一直在尝试使用模板文字,但我想我只是不明白,现在我很沮丧.我的意思是,我想我明白了,但它"不应该是它如何运作,或者它应该如何获得.应该会有所不同.

I've been trying to use template literals but I guess I just don't get it and now I'm getting frustrated. I mean, I think I get it, but "it" shouldn't be how it works, or how it should get. It should get differently.

我看到的所有示例(甚至标记模板)都要求在声明时而不是运行时完成替换",这对我来说对于模板来说似乎完全没用.也许我疯了,但对我来说,模板"是一个包含令牌的文档,这些令牌在您使用它时会被替换,而不是在您创建它时被替换,否则它只是一个文档(即字符串).模板与标记一起存储作为标记 &当你......评估它时,这些令牌会被评估.

All the examples I see (even tagged templates) require that the "substitutions" be done at declaration time and not run time, which seems utterly useless to me for a template. Maybe I'm crazy, but a "template" to me is a document that contains tokens which get substituted when you use it, not when you create it, otherwise it's just a document (i.e., a string). A template is stored with the tokens as tokens & those tokens are evaluated when you...evaluate it.

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

Everyone cites a horrible example similar to:

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

这很好,但如果我已经知道 a,我只会返回 'Worthless asd'返回 'Worthless '+a.重点是什么?严重地.好吧,关键是懒惰;更少的优点,更多的可读性.伟大的.但这不是模板!不是恕我直言.而 MHO 才是最重要的!恕我直言,问题在于模板在声明时会进行评估,因此,如果您这样做,恕我直言:

That's nice, but if I already know a, I would just return 'Worthless asd' or return 'Worthless '+a. What's the point? Seriously. Okay the point is laziness; fewer pluses, more readability. Great. But that's not a template! Not IMHO. And MHO is all that matters! The problem, IMHO, is that the template is evaluated when it's declared, so, if you do, IMHO:

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

由于 expletive 没有被声明,它会输出类似 My undefined template 的内容.极好的.实际上,至少在 Chrome 中,我什至不能声明模板;它抛出一个错误,因为 expletive 没有定义.我需要的是能够在声明模板后进行替换:

Since expletive isn't declared, it outputs something like My undefined template. Super. Actually, in Chrome at least, I can't even declare the template; it throws an error because expletive is not defined. What I need is to be able to do the substitution after declaring the template:

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

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

However I don't see how this is possible, since these aren't really templates. Even when you say I should use tags, nope, they don't work:

> 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...

这一切让我相信模板字面量被严重错误地命名,应该被称为它们真正的名字:heredocs.我想文字"部分应该让我失望(例如,不可变)?

This all has led me to believe that template literals are horribly misnamed and should be called what they really are: heredocs. I guess the "literal" part should have tipped me off (as in, immutable)?

我错过了什么吗?有没有(好的)方法来制作可重用的模板文字?

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

> 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!

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

And here is a naive "helper" function...

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

...让它更好".

我倾向于称它们为模板,因为它们会产生曲折的感觉.

I'm inclined to call them template guterals because of the area from which they produce twisty feelings.

推荐答案

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

To make these literals work like other template engines there needs to be an intermediary form.

最好的方法是使用 Function 构造函数.

The best way to do this is to use the Function constructor.

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));

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

As with other template engines you can get that string from other places like a file.

使用这种方法可能会出现一些问题,例如模板标签难以使用,但如果您很聪明,可以添加这些问题.由于后期插值,您也无法使用内联 JavaScript 逻辑.这也可以通过一些想法来补救.

There can be issues using this method like template tags are hard to use, but those can be added if you're clever. You also can't have inline JavaScript logic because of the late interpolation. This can also be remedied with some thought.

这篇关于ES6 模板文字可以在运行时替换(或重用)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆