调用函数的反引号

IT技术 javascript ecmascript-6 template-strings template-literals tagged-templates
2021-01-27 20:47:55

我不知道如何解释这一点,但是当我跑步时

console.log`1`

在谷歌浏览器中,我得到的输出是

console.log`1`
VM12380:2 ["1", raw: Array[1]]

为什么反引号调用 log 函数,为什么它会创建一个索引raw: Array[1]

问题由 Catgocat 在 JS 房间提出,但除了模板字符串的一些内容之外,没有任何答案有意义,这些字符串并不真正适合为什么会发生这种情况。

3个回答

它在 ES-6 中被称为标记模板,更多可以阅读它们在这里有趣的是我在聊天的加星标部分找到了链接。

但是代码的相关部分如下(您基本上可以创建过滤排序)。

function tag(strings, ...values) {
  assert(strings[0] === 'a');
  assert(strings[1] === 'b');
  assert(values[0] === 42);
  return 'whatever';
}
tag `a${ 42 }b`  // "whatever"

基本上,它只是用 console.log 函数标记“1”,就像它对任何其他函数所做的那样。标记函数接受模板字符串的解析值和可以执行进一步任务的单独值。

Babel 将上述代码转译为

var _taggedTemplateLiteralLoose = function (strings, raw) { strings.raw = raw; return strings; };

console.log(_taggedTemplateLiteralLoose(["1"], ["1"]));

正如你在上面的例子中看到的,在被 babel 转译后,标记函数(console.log)被传递了以下 es6->5 转译代码的返回值。

_taggedTemplateLiteralLoose( ["1"], ["1"] );

这个函数的返回值被传递给console.log,然后它将打印数组。

我发现这是一个更容易理解的解释-wesbos.com/tagged-template-literals
2021-04-06 20:47:55

标记模板文字:

以下语法:

function`your template ${foo}`;

称为标记模板文字。


作为标记模板文字调用的函数以下列方式接收其参数:

function taggedTemplate(strings, arg1, arg2, arg3, arg4) {
  console.log(strings);
  console.log(arg1, arg2, arg3, arg4);
}

taggedTemplate`a${1}b${2}c${3}`;

  1. 第一个参数是所有单个字符串字符的数组
  2. 剩余的参数与我们通过字符串插值接收到的变量值相对应。请注意,在示例中没有值arg4(因为只有 3 次字符串插值),因此undefined在我们尝试记录时会记录arg4

使用 rest 参数语法:

如果我们事先不知道在模板字符串中会发生多少次字符串插值,那么使用 rest 参数语法通常很有用。此语法将函数接收到的剩余参数存储到数组中。例如:

function taggedTemplate(strings, ...rest) {
  console.log(rest);
}

taggedTemplate `a${1}b${2}c${3}`;
taggedTemplate `a${1}b${2}c${3}d${4}`;

迟到了,但是,TBH,没有一个答案能解释 50% 的原始问题(“为什么raw: Array[1]”)

1. 为什么可以使用反引号调用不带括号的函数?

console.log`1`

正如其他人指出的那样,这称为标记模板(更多详细信息也在这里)。

使用此语法,该函数将接收以下参数:

  • 第一个参数:一个包含字符串的不同部分的数组,这些部分不是表达式。
  • 其余参数:正在插入的每个值(即那些表达式)。

基本上,以下是“几乎”等效的

// Tagged Template
fn`My uncle ${uncleName} is ${uncleAge} years old!`
// function call
fn(["My uncle ", " is ", " years old!"], uncleName, uncleAge);

(请参阅第 2 点。了解为什么它们不完全相同)

2. 为什么["1", raw: Array[1]]???

作为第一个参数传递的数组包含一个属性raw,允许在输入原始字符串时访问它们(不处理转义序列)。

示例用例:

let fileName = "asdf";

fn`In the folder C:\Documents\Foo, create a new file ${fileName}`

function fn(a, ...rest) {
  console.log(a); //In the folder C:DocumentsFoo, create a new file
  console.log(a.raw); //In the folder C:\Documents\Foo, create a new file 
}

什么,一个有属性的数组??????

是的,因为 JavaScript 数组实际上是对象,它们可以存储属性

例子:

const arr = [1, 2, 3];
arr.property = "value";
console.log(arr); //[1, 2, 3, property: "value"]