6

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

上下文:我知道其他方法可以做到这一点,例如使用模板库或执行多个查找和替换,但我想知道 ES6 的任何部分是否支持开箱即用的这个用例。我浏览了 ECMAScript 6.0 标准的模板文字部分,它非常清楚地说明"Let ctx be the running execution context"了但似乎很难相信它们不会在必要时提供一种明确的上下文的方法。

4

3 回答 3

7

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

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

于 2017-09-26T19:23:12.930 回答
2

您可能想在Javascript MDN上阅读更多关于它们的内容,并注意名为Tagged template literals的部分,因为它展示了如何将模板文字转换为完整的模板。

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

标记的模板文字

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

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

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

于 2017-09-26T19:07:13.927 回答
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'} ));
于 2017-09-26T19:19:13.873 回答