将JS对象作为范围传递给JS Template Literal?

时间:2017-09-26 18:57:54

标签: ecmascript-6 template-literals

在python中,你可以像这样进行变量字符串插值:

song_context = { "adjective": "funny" }
ella_sings = "my {adjective} valentine".format(**song_context)

此处,song_context对象格式化ella_sings字符串中的变量。

在ES6中是否有一种内置方法可以使用模板文字执行此类操作?我正在寻找一种快速的方法来明确定义给定字符串的替换空间。例如:

const song_context = { adjective: "funny" }
const ella_sings = `my ${adjective} valentine`.format(song_context)

背景信息:我知道其他方法,例如:使用a template librarymultiple find and replace,但我想知道ES6的任何部分是否支持开箱即用的这个用例。我浏览了template literal part of the ECMAScript 6.0 standard并且非常清楚地说明了"Let ctx be the running execution context",但似乎很难相信他们不会提供一种方法来更明确地显示关于上下文的信息。必要的。

3 个答案:

答案 0 :(得分:4)

  

在ES6中是否有内置的方法可以使用模板文字做这样的事情?

模板文字没有特殊的逻辑。 ${..}括号之间的代码只是一个正常的表达式,它被评估为一个值。

`my ${adjective} valentine`

始终将在本地范围内查找名为adjective的变量。你当然可以改变它来做

`my ${song_context.adjective} valentine`

如果你不想改变它的那一部分,那么你总是可以使用解构,例如

const {adjective} = song_context;
const ella_sings = `my ${adjective} valentine`

或使用IIFE:

const ella_sings = ({adjective}) => `my ${adjective} valentine`)(song_context);

如果需要,您还可以围绕模板文字构建自己的模板系统,但它开始变得复杂,并且失去了大部分让您想要首先使用模板文字的好处。

答案 1 :(得分:1)

您可能希望在Javascript MDN上详细了解它们,并注意名为标记模板文字的部分,因为它显示了如何将模板文字转换为完整的模板。

出于档案目的,我将导入相关部分:

标记模板文字

更高级的模板文字形式是标记模板文字。标签允许您使用函数解析模板文字。标记函数的第一个参数包含一个字符串值数组。其余参数与表达式相关。最后,您的函数可以返回被操纵的字符串(或者它可以返回完全不同的内容,如下一个示例中所述)。用于标记的函数名称可以根据需要命名。

var person = 'Mike';
var age = 28;

function myTag(strings, personExp, ageExp) {

  var str0 = strings[0]; // "that "
  var str1 = strings[1]; // " is a "

  // There is technically a string after
  // the final expression (in our example),
  // but it is empty (""), so disregard.
  // var str2 = strings[2];

  var ageStr;
  if (ageExp > 99){
    ageStr = 'centenarian';
  } else {
    ageStr = 'youngster';
  }

  return str0 + personExp + str1 + ageStr;

}

var output = myTag`that ${ person } is a ${ age }`;

console.log(output);
// that Mike is a youngster

标记函数不需要返回字符串,如以下示例所示。

function template(strings, ...keys) {
  return (function(...values) {
    var dict = values[values.length - 1] || {};
    var result = [strings[0]];
    keys.forEach(function(key, i) {
      var value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join('');
  });
}

var t1Closure = template`${0}${1}${0}!`;
t1Closure('Y', 'A');  // "YAY!"
var t2Closure = template`${0} ${'foo'}!`;
t2Closure('Hello', {foo: 'World'});  // "Hello World!"

这些标记的模板文字似乎正是您想要的。

答案 2 :(得分:1)

您可以创建一个编译模板的函数,然后接受上下文作为参数。唯一的问题是你需要在花括号内围绕占位符放置引号。

const compileTemplate = (template, ...replacements) => 
    ctx => 
        template.reduce(
            (accumulator, part, i) => 
                accumulator + ctx[replacements[i - 1]] + part

            );


const templateFn = compileTemplate`This is a ${'adj'} problem.`;

console.log(templateFn( {adj: 'hard'} ));
console.log(templateFn( {adj: 'funny'} ));