ES6标记的模板函数如何解释它们的参数顺序?

时间:2014-07-18 03:28:37

标签: javascript ecmascript-6 template-strings

请考虑以下代码:

function f() {
  console.log(Array.from(arguments));
}

var x = 2;
var y = 3;
f`before ${x} ${y} after`;

f的论据是(according to Traceur):

["before ", " ", " after"], 2, 3

我想说我想用替换值连接所有文字字符串 我该如何按正确的顺序做到这一点?

我是否需要匹配“分裂点”'在第一个数组中,每个参数在第一个之后?

2 个答案:

答案 0 :(得分:2)

根据ECMAScript 6规范草案的维基,它更复杂,因为模板考虑了转义序列:

模板

quasiTag`literalPortion\0 $x literalPortion1`

将desugar到

// Declaration hoisted to top of module.
// Escape sequences in the hoisted declaration are not decoded according to CV(EscapeSequence).
// The calls to Object.freeze use the original definition of that method.
const unguessableCallSiteId1234 = Object.freeze({
  raw: Object.freeze(["literalPortion\\0 ", "literalPortion1"]),
  cooked: Object.freeze(["literalPortion\u0000 ", "literalPortion1"])
});

...

  // In-situ
  // Escape sequences in the arguments are decoded.
  // unguessableCallSiteId1234 is ideal as a key into a weak map used to memoize
  // extraction of meta-data, custom escaping conventions, and other state
  // that can be derived from the literal portions, so does not vary from
  // call to call from the same call-site.
  quasiTag(unguessableCallSiteId1234, x)
     

EcmaScript Quasi-Literals - Desugaring

所以arguments应该包含替换值,就像你在traceur中看到的那样,但是文字部分是一个对象,而不是一个数组。

如果您想为使用traceur编译的代码实现它,您可以执行类似以下未经优化的示例。

let concatenated = "";
Array.forEach(args[0], (e, i) =>
    concatenated += e + ( i < arguments.length - 1 ? arguments[i+1] : "")
);

对于真正的ECMAScript 6代码,请查看Default Quasi Tag实现,如评论中建议的bergi。

答案 1 :(得分:2)

除了替换之外,总有一个字面部分。第一个文字是模板的第一部分(如果它以替换开头,则为空字符串),最后一个文字是模板字符串的尾部(或者,如果它以替换结束,则为空字符串)。 / p>

要按顺序获取部分,请访问literal[0]sub[0]literal[1],...,sub[sub.length-1]literal[sub.length]

这是一个简单的起点:

function simpleTag(lit, ...sub) {
  return sub.reduce(
    // Add next substition and following literal
    (soFar, s, i) => soFar + s + lit[i+1],
    lit[0] // Start with the first literal
  );
}