When you call String([]), the method Array.prototype.toString is eventually called, and according to the spec of Array.prototype.toString, the steps are:
- Let array be the result of calling ToObject on the this value.
- Let func be the result of calling the [[Get]] internal method of array with argument "join".
- If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
- Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.
You can figure out that it then actually calls Array.prototype.join and returns its result. The spec of Array.prototype.join is a little bit longer but the step 8 is the root cause confusing you:
- If element0 is
undefined or null, let R be the empty String; otherwise, Let R be ToString(element0).
Which means when Array.prototype.join iterates all of the elements, whenever it meets undefined or null, it'll replace it by empty String, and the default delimiter of join is ,. That's why String([undefined]) gives you "", because there's only one element in the array and it's undefined, if you try String([undefined, null]), you'll get ","(two empty string joined by ,), and String([null, undefined, 1]) will give you ",,1"
A little snippet to prove Array.prototype.toString calls Array.prototype.join:
console.log(String([undefined]))
console.log(String([1,2,3]))
console.log("----------Override Array.prototype.join--------")
Array.prototype.join = function() {
return "I don't care what is in the original array";
}
console.log(String([undefined]))
console.log(String([1,2,3]))
BTW, there's an awesome blog talking about how to convert value to String in Javascript, hope it helps.
Regards:-)