为什么模板字符串(``)作为函数执行前面的标记?

时间:2016-12-08 16:44:17

标签: javascript function ecmascript-6 template-strings

我今天遇到了一个错误 - TypeError: "fa" is not a function - 经过短暂的调查后,我找到了原因。我忘记了一个对象文字中的逗号,这给我留下了一个字符串后面跟一个模板字符串,基本上就是这个:"fa"``。看过not a function我希望找到一些令人讨厌的括号并发现这很奇怪,所以我加深了对Node REPL的调查。

''``               // TypeError: '' is not a function
'foo'``            // TypeError: 'foo' is not a function
1``                // TypeError: 1 is not a function
(() => 'foobar')`` //'foobar'

好的,所以我发现模板字符串似乎与在令牌之后放置括号类似。 Curiouser和curiouser。

我想知道它是否传递任何参数,所以我写了这个:

function showArgs () {
  return arguments
}

showArgs()                  // {}
showArgs``                  // { '0': [ '' ] }
showArgs`foo`               // { '0': [ 'foo' ] }
showArgs`foo${'bar'}`       // { '0': [ 'foo', '' ], '1': 'bar' }
showArgs`foo${'bar'}${1}`   // { '0': [ 'foo', '', '' ], '1': 'bar', '2': 1 }
showArgs(`foo${'bar'}${1}`) // { '0': 'foobar1`' }

这里发生了什么?

这些参数显然与模板字符串有关,因为它们可以通过将 n 数组项与 n + 1 结合来构造它。参数并将它们全部加入,但为什么模板字符串使用这些参数执行前面的标记?

1 个答案:

答案 0 :(得分:3)

查看tagged template literals

  

更高级的模板文字形式是标记模板文字。使用它们,您可以使用函数修改模板文字的输出。第一个参数包含一个字符串文字数组[...]。第二个,以及第一个之后的每个参数,是已处理(或有时称为 cooked )替换表达式的值[...]。最后,您的函数返回被操纵的字符串。

MDN的一个例子:

var a = 5;
var b = 10;

function tag(strings, ...values) {
  console.log(strings[0]); // "Hello "
  console.log(strings[1]); // " world "
  console.log(strings[2]); // ""
  console.log(values[0]);  // 15
  console.log(values[1]);  // 50

  return "Bazinga!";
}

tag`Hello ${ a + b } world ${ a * b }`;
// "Bazinga!"