I've spent hours researching documents in order to answer your question. And I'll try my best to explain it simply.
My first answer is, in fact, a text explanation. However, I remember W3Schools once said that:
Examples are better than 1000 words. Examples are often easier to
understand than text explanations.
Well then, this answer supplements all explanations with clarifying "Try it Yourself" examples.
There are two concepts in Javascript that involved: the Tagged templates and the Console.log() method.
I'll re-write your codes, breaking them into two parts, like this: (the executed result remains the same).
// part 1
function say(something) {
return something;
}
let name = `Reza`;
let output = say`My name is`;
// part 2
console.log(output, name, '!');
Let's see how these two parts related to the concepts of Tagged templates and the Console.log() method, respectively.
First, examine this example:
Example 1:
function say(something) {
return something;
}
let output = say`My name is`;
console.log(output)
After running this example, we'll see an array
that contains one element which is a string
: "My name is"
This is the behavior of the Tagged templates
Before we actually dive into how Tagged templates works, let's take a look at some examples below:
Example 2:
function say(something) {
return something[0];
}
let output = say`My name is`;
console.log(output)
After running the example 2, we'll receive a string
: "My name is", instead of an array
as the example 1 did.
Well then, what if I want to pass a name
to it? see this:
Example 3
function say(something, name) {
return `${something[0]}${name}`;
}
let name = 'Reza';
let output = say`My name is ${name}`;
console.log(output)
Yay! It works as expected. Well then, what if I want to pass two arguments instead of one? see this:
Example 4
function say(something, name, age) {
let str0 = something[0];
let str1 = something[1];
let str2 = something[2];
return `${str0}${name}${str1}${age}${str2}`;
}
let name = 'Reza';
let age = 1000;
let output = say`My name is ${name}, I'm ${age} years old!`;
console.log(output)
Quite clear, right? This is how we use Tagged templates.
The examination of the Tagged templates is done now. Let's see how Console.log()
method works.
Example 5
console.log(`My name is `)
We are all familiar with this usage of Console.log() method, passing one argument. Well then, what if I want to pass multiple arguments to it. See this:
Example 6
let name = `Reza`;
console.log(`My name is `, name, '!')
It combined all together into one single output.
Well then, for now, let's go back to your sample:
function say(something) {
return something; // the `something` is still an array
}
let name = `Reza`;
console.log(say `My name is`, name, '!');
// the console.log() method will try to combine all these three arguments
// into one single output
// this is why we got the output as an array with a string: "name" and a string: "!"
We could fix it like this:
Example 7
function say(something) {
return something[0];
}
let name = `Reza`;
console.log(say`My name is`, name, '!');
Or like this:
Example 8
function say(something, name) {
return `${something[0]}${name}`;
}
let name = `Reza`;
console.log(say`My name is ${name} `, '!');
However, let's see this example:
Example 9
function say(something, name) {
return `${something[0]}${name}`;
}
let name = `Reza`;
console.log(say`My name is ${name} `, name, '!');
We'll receive My name is Reza Reza !
. I believe that, for now, we all understand why we got it.