The .call()
method is used on functions, it behaves in a similar way to using ()
to call a function such as when you perform functionName()
, however, it allows you to explicitly define what the this
is inside of the function, so for example:
function functionName(arg) {
console.log("this", this); // this {"foo": 1}
console.log("arg", arg); // arg str
}
functionName.call({foo: 1}, "str");
Notice that above, the first argument to .call()
defines what this
is inside of your function, and then the second argument onwards defines what the arguments are to functionName
.
We can use .call()
on any function, including the ones provided to us by JavaScript. In your code, you're using [].join
which exposes (not calls) the join
function of arrays, that is, it gives you access to the join
function defined on the Array.prototype
object. With that in mind, your code could be rewritten like so to highlight that [].join
is used just to obtain the join
function from the array prototype:
function func() {
const joinFn = Array.prototype.join; // or: [].join;
console.log(joinFn.call(arguments));
}
func('a', 'b', 'c'); // "a,b,c"
Internally, the .join()
method on arrays uses this
inside of it (similar to how functionName()
uses this
inside of it) to determine what object/array needs its elements to be "joined" together. In your example, you are not calling .join
directly on your empty array (ie: [].join()
), but instead, are using the empty array to access the .join
function, and then calling it with the arguments
object by using join.call(arguments)
. When you do this, the this
inside of the .join()
method is set to the arguments
object and the join method is called with no arguments, so the separator defaults to ,
. As the arguments
object is array-like (it has indexes and a length
property like an array does), its elements can be joined together just like an array's elements can be joined together.
You can see section 23.1.3.15 of the ECMAScript specification for further details on how Array.prototype.join
works internally and how it is made generic to handle array-like objects and not just arrays.