I can't quite understand why the join() call below produces different results, depending on the type of argument(s) provided.
Here's what I found:
var test = function() {
var args = Array.prototype.join.call(arguments,"_");
return args
};
console.log(test([1,2,3])) // #1: returns 1,2,3
console.log(test(1,2,3)) // #2: returns 1_2_3
Given join(arguments, '_'), shouldn't it produce a _
delimited string in both tests above? Why does #1 return a comma delimited value instead?
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.
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]))
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("_"));
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
.
Because you're passing one argument which is an array - so it converts it to a string, then attempts to join it to the other arguments (there are none) so it just returns the string.
var test = function() {
var args = Array.prototype.join.call(arguments, "_");
return args
};
console.log(test([1, 2, 3]));
console.log(test(1, 2, 3));
You can solve this by checking if there's only one argument passed.
var test = function() {
var args = arguments.length == 1 ? arguments[0].join("_") : Array.prototype.join.call(arguments, "_");
return args;
};
console.log(test([1, 2, 3]));
console.log(test(1, 2, 3));
The result is different, because arguments
is different.
On the first call (test([1,2,3])
, you have one argument which is an array.
On the second call, you have 3 arguments, each one being a number.
Array.prototype.join
is meant to be called over arrays. It will stringify each of the items in the array.
In you your first case, your arguments "array" has only one member, which is an array itself. This argument will be stringfied. An array stringfied becomes exactly what is logged in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With