How does join() produce different results depending on the arguments?
In the first example you are not calling .join
on the array but on arguments
. That variable will be populated with an array-like object that has an array as first index, in essence, you are calling the equivalent of:
let myArguments = [[1, 2, 3]];
console.log(myArguments.join("_"));
instead of what you do (the equivalent of) in the second example:
let myArguments = [1, 2, 3];
console.log(myArguments.join("_"));
In your code, you only have one argument in the first example, that being an array. Joining a single element will remove the brackets:
var test = function() {
var args = Array.prototype.join.call(arguments,"_");
return args
};
console.log(test([1,2,3])) // args = [[1,2,3]]
console.log(test(1,2,3)) // args = [1,2,3]
console.log([[1,2,3]].join('_'))
console.log([1,2,3].join('_'))
Another way to look at this is to provide another array as an argument to test()
:
var test = function() {
var args = Array.prototype.join.call(arguments,"_");
return args
};
console.log(test([1,2,3], [4,5,6]))
The first one, first argument is [1,2,3]
which is joined with the second argument, which is nothing -> output is [1,2,3].toString()
.
Second call, it's actually joining all the 3 arguments, resulting in outputting 1_2_3
.
When you pass an array to test
, the arguments
object becomes an array of arrays, not a plain array of plain values. It's the difference between
arguments = [[1,2,3]];
and
arguments = [1,2,3];
When you call .join
on an array of arrays, each inner array gets implicitly coerced to a string first, resulting in '1,2,3'
- the values of the inner arrays do not get .join
ed by the delimiter, only the immediate children of the outer array get .join
ed by the delimiter.