Gwater17 Gwater17 - 2 months ago 6x
Javascript Question

How can an empty string plus an object equal a number

v = {
toString: function () { return 'foo' },
valueOf: function () { return 5 }
console.log('' + v); //5
console.log(v); // { [Number: 5] toString: [Function], valueOf: [Function] }

Why does the v object get the value of 5?


You are creating an object, v, and overriding its valueOf() method to return the integer 5. If an object does not have an explicit valueOf() method defined, then valueOf() returns the object itself. All built-in core objects in JavaScript override this method to return the appropriate value. For example, doing the following:

x = 5;

is really doing:

console.log(x.valueOf()) // log the return value of x.valueOf()

You can read more about valueOf() here:

If you are asking about why the addition (+) operator returns an arithmetic addition (calling v.valueOf()) instead of concatenation, you need to refer to the ECAMScript specification for the answer. Section 11.6.1 talks about the addition operator. Here is the relevant bit:

  1. Let lprim be ToPrimitive(lval).
  2. Let rprim be ToPrimitive(rval).
  3. If Type(lprim) is String or Type(rprim) is String, then Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
  4. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim).

It looks like the operands should be resolved into string types before number types, so your expression ''+v should call v.toString() first, and thus return foo, right?

Actually, no. Because in step 5 and 6, both operands are resolved into their primitives first, and this resolution is done without "hint". When there is no hint passed to ToPrimitive, Objects return their default values, which is the return of the valueOf() method. See section 9.1 for how Objects resolve into their primitives.