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

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

问题描述

tl; dr:可以使一个可重复使用的模板文字吗?



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



我看到的所有示例(甚至标记的模板)都要求在声明时间完成替换,而不是运行时间,这似乎完全没用给我一个模板也许我很疯狂,但是对我来说,一个模板是一个包含使用它时被替代的令牌的文档,而不是创建它,否则它只是一个文档(即一个字符串)。模板与令牌一起存储为令牌&每个人都引用了一个可怕的例子:

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

这很好,但是如果我已经知道 a ,我只会 return'Worthless asd' return'Worthless'+ a 。重点是什么?认真。好的一点是懒惰;更少的优点,更多的可读性。大。但这不是一个模板!不是IMHO。和MHO是重要的!问题IMHO是,模板在被声明时被评估,所以如果你这样做,那么IMHO:

  var tpl = `我的$ {expletive}模板`; 
function go(){return tpl; }
go(); //空间结束!

由于 expletive 未声明,输出像我未定义的模板。超。实际上,至少在Chrome中,我甚至不能声明模板;它会引发错误,因为没有定义 expletive 。我需要的是在声明模板后能够进行替换:

  var tpl =`我的$ {expletive}模板`; 
function go(){return tpl; }
var expletive ='great';
go(); //我的好模板

然而,我看不到这是可能的,因为这些不是真正的模板。即使你说我应该使用标签,不,他们不工作:

 > 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未捕获ReferenceError:未定义expletive ...

这一切都让我相信模板文字被错误地命名,应该被称为真正的东西: heredocs 。我想文字部分应该把我关掉(如在,不变的)?



我错过了什么吗?是否有一个[好的]方式来制作可重复使用的模板文字?






我给你, > 可重复使用的模板文字

 > function out(t){console.log(eval(t)); 
var template =`\`这是
我的\ $ {expletive}可重用
template!\``;
out(template);
var expletive ='好奇';
out(template);
var expletive ='AMAZING';
out(template);
<这是
我的未定义的可重用的
模板!
这是
我好奇的可重用
模板!
这是
我的AMAZING可重用
模板!

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

 函数t(t){return'`'+ t.replace('{','$ {')+' } 
var template = t(`这是
我的{expletive}可重用
模板!

...让它更好。



/ p>

解决方案

你可以将它们称为模板guterals,因为它们产生扭曲的感觉。可以将模板字符串放在函数中:

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

您可以使用标记的模板执行相同的操作:

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

var tagged = reusable`a是$ {0},b是$ {1}`; // dummyparameters
console.log(tagged(hello,world));
//打印a is hello b is world
console.log(tagged(mars,jupiter));
//打印a is mars b is jupiter

这个想法是让模板解析器从变量slots中分离出常量字符串,然后返回一个函数,它每次基于一组新的值将其全部重新整理。


tl;dr: Is it possible to make a reusable template literal?

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

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!

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

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

Am I missing something? Is there a [good] way to make a reusable template literal?


I give you, reusable template literals:

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

...to make it "better".

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

解决方案

You can put a template string in a function:

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

You can do the same thing with a tagged template:

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"

The idea is to let the template parser split out the constant strings from the variable "slots", and then return a function that patches it all back together based on a new set of values each time.

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

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