Reputation: 2639
I know you can use template literals to supply the first parameter of a method, for instance:
const f = x => "hello ," + x;
f`world` // returns 'hello, world'
So I can somehow understand why this code works:
String.raw`bla bla`
However, I can't seem to understand why the same method call with parenthesis throws an error:
String.raw(`bla bla`)
throws: Uncaught TypeError: Cannot convert undefined or null to object
My questions are:
Why exactly the first snippet works? why can I replace parenthesis with template literals in a method call?
Why String.raw
only works when it's being called this way?
Upvotes: 3
Views: 1277
Reputation: 1075109
... I can't seem to understand why the same method call with parenthesis throws an error
It's not the same method call.
This:
String.raw`bla blah`
...calls raw
passing in the template.
But this:
String.raw(`bla blah`)
...processes the template, creating a string, and then calls raw
with that string. Exactly as though you'd written:
const str = `bla blah`;
String.raw(str);
...but without the constant.
That's not the same thing at all.
Why exactly the first snippet works?
Because that's how tagged template literals work. They're their own thing.
Why
String.raw
only works when it's being called this way?
Because it's designed to be run as a tag function, but you're calling it like a non-tag function and not passing it the information a tag function receives when called as a tag function.
It might help if you see what a tag function receives:
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`;
Note how the function receives an array with the non-token parts of the template (the "strings"), followed by arguments with the values of each token. Also note that those values are the actual values, not strings of the values.
More about template literals and tag functions:
Upvotes: 6
Reputation: 3687
Or if you want to call String.raw as a function you need to call it like this
String.raw({raw: `xyx`})
As mentioned in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw documentation
Two ways of calling String.raw
String.raw(callSite, ...substitutions)
String.raw`templateString`
Upvotes: 2