All of the following discussion must meet a condition that is not your own self toString valueOf method and the method definition of the object.
First three predefined variables a, b, c. And to change their methods toString and valueOf
var a = new Number(123);
a.toString = function(){
console.log('call a.toString');
return new Number(123).toString();
};
a.valueOf = function(){
console.log('call a.valueOf');
return new Number(123).valueOf();
};
var b = new String('b-string');
b.toString = function(){
console.log('call b.toString');
return new String('b-string').toString();
};
b.valueOf = function(){
console.log('call b.valueOf');
return new String('b-string').valueOf();
};
var c = {}
c.toString = function(){
console.log('call c.toString');
return {}.toString();
};
c.valueOf = function(){
console.log('call c.valueOf');
return {}.valueOf();
};
When using Number () Casts
var res = Number(a);//call a.valueOf
console.log(a);//123
var res = Number(b);//call b.valueOf
console.log(b);//NaN
var res = Number(c);/*call c.valueOf
call c.toString
*/
console.log(c);//NaN
The above code shows, when using Number () be cast, when the parameter is new new Number () or a new String (), call valueOf function; when the parameter is {}, first call valueOf function, then call toString function .
When using the String () Casts
var res = String(a);//call a.toString
console.log(res);//123
var res = String(b);//call b.toString
console.log(res);//b-string
var res = String(c);//call c.toString
console.log(res);//[object Object]
Codes described above, when a String () for casts for new Number (), new String (), and {}, the function calls the toString.