2
var x = undefined;String(x); // "undefined"
var y = [x];String(y); // ""

Why above output different value?
It confuse me.


Why String(undefined) returns undefined but String([undefined]) returns ''?
What makes difference with the results?
Thanks!

3 Answers 3

3

When you call String([]), the method Array.prototype.toString is eventually called, and according to the spec of Array.prototype.toString, the steps are:

  1. Let array be the result of calling ToObject on the this value.
  2. Let func be the result of calling the [[Get]] internal method of array with argument "join".
  3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
  4. 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:

  1. 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:-)

Sign up to request clarification or add additional context in comments.

1 Comment

Good to see references to ECMA-262, but ed 5.1 has been superceded by ECMAScript 2015 and 2016 and is about to yet again by 2017. ;-)
0

Javascript is a bit funny on casting.

On the first one, you are casting an undefined value. All it does is literally write that text.

On the second one, you are casting an array with values. Hence, the process is different. Try: var z = [x, x]; String(z); // returns ","

Same happens if you do: var x = null; String(x); var y = [x]; String(y);

What your assumption is that String([undefined]) will do is cast each value as String(), then concatenate them. However, strings are basically arrays of characters. If you have an array with nothing in it (i.e. undefined, null), it just makes an empty string.

There are other examples of funny "inconsistencies" like that:

[] + {} // returns [object Object]
{} + [] // returns 0

5 Comments

sry, I have read your answer, it is vert clear.But, it seems that you still don't tell why difference or I misunderstand?
To add on to Fabian's answer, strings are basically arrays of characters. If you have an array with nothing in it (i.e. undefined, null), it just makes an empty string.
Adding that note to the reply. Thanks, Matheus.
You are making things more difficult than they need to be. How the + operator behaves depends on context (and has nothing to do with the OP).
BTW, in {}+[] the braces ({}) are treated as a empty block, not an Object literal, so the expression resolves to +[], which is effectively Number([]), which returns the number 0.
0

You could always just read ECMA-262.

When String is called as a function with one value, it returns (more or less) ToString(value).

Calling ToString(undefined) returns the string "undefined", which explains the first result.

Similarly for the the second case, except that since Arrays are Objects, calling ToString(arrayInstance) first calls ToPrimitive. That will call the array's toString method, which is effectively array.join(',').

Since the array only has one member and its value is undefined, join returns an empty string. Try it:

console.log( '"' + [undefined].toString() + '"');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.