带字符串的String.raw只能在不带括号的情况下工作

时间:2018-01-17 14:07:09

标签: javascript ecmascript-6

我知道您可以使用模板文字来提供方法的第一个参数,例如:

const f = x => "hello ," + x;
f`world` // returns 'hello, world'

所以我可以理解为什么这段代码有效:

String.raw`bla bla`

但是,我似乎无法理解为什么使用括号调用相同的方法会抛出错误:

String.raw(`bla bla`)

抛出:Uncaught TypeError: Cannot convert undefined or null to object

我的问题是:

  • 为什么第一个代码段正常工作?为什么我可以在方法调用中用模板文字替换括号?

  • 为什么String.raw仅在以这种方式调用时有效?

2 个答案:

答案 0 :(得分:4)

  

...我似乎无法理解为什么用括号调用相同的方法会抛出错误

这与方法调用不同。

此:

String.raw`bla blah`

...调用raw传递模板

但是这个:

String.raw(`bla blah`)

...处理模板,创建一个字符串,然后用该字符串调用raw。就像你写的那样:

const str = `bla blah`;
String.raw(str);

......但没有常数。

这根本不是一回事。

  

为什么第一个代码段确实有效?

因为标记的模板文字的工作原理。他们是他们自己的东西。

  

为什么String.raw仅在以这种方式调用时才有效?

因为它被设计为作为标记函数运行,但是你将其称为非标记函数,而不是将标记函数作为标记函数调用时接收的信息传递给它。

如果你看到标签功能收到了什么可能会有所帮助:

function foo(strings, ...tokenValues) {
    console.log("strings: ", JSON.stringify(strings));
    console.log("strings.raw: ", JSON.stringify(strings.raw));
    console.log("Token values (" + tokenValues.length + "):");
    tokenValues.forEach((val, index) => {
      console.log(`${index}: ${typeof val}: ${JSON.stringify(val)}`);
    });
}
const token = "tokenValue";
const obj = {
   foo: "bar",
   num: Math.random()
};
foo`bla \nbla ${token} bla ${obj} done`;

注意函数如何接收带有模板的非标记部分(“字符串”)的数组,后跟带有每个标记值的参数。另请注意,这些值是实际值,而不是值的字符串。

有关模板文字和标记函数的更多信息:

答案 1 :(得分:1)

或者如果你想将String.raw作为一个函数调用,你需要像这样调用它

String.raw({raw: `xyx`})

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw文档中所述

调用String.raw的两种方法

String.raw(callSite, ...substitutions)

String.raw`templateString`