Is there any expression where by an object\'s toString method is implicitly called overriding its valueOf method?
In the examples below, valueOf is alw
Is there any expression
Yes. Here's an example that will use toString
:
alert({
toString: function () {
return "4";
},
valueOf: function () {
return 6;
}
}); // alerts "4"
Is there any expression where by an object's toString method is implicitly called overriding its valueOf method?
Yes, that does happen whenever the abstract ToString operation is applied on an object, using the DefaultValue procedure with .toString()
before .valueOf()
.
However, in your examples you have only used the addition operator which is like an exception from the standard behaviour. Since it does not only concatenate strings, but also sums numbers, it always uses valueOf
on both operands before checking whether they're strings. See the note 1:
No hint is provided in the calls to ToPrimitive in steps 5 and 6. All native ECMAScript objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Host objects may handle the absence of a hint in some other manner.
So which operations do implicitly use the ToString
instead of a hint-less ToPrimitive
? Here are a few examples:
in
operator, bracket notation, Object.getOwnPropertyDescriptor
, Object.defineProperty
, hasOwnProperty
, …parseInt
, parseFloat
, encodeURI[Component]
, decodeURI[Component]
, [un]escape
, Array::join
, String::[last]indexOf
, RegExp::exec
Function
constructorArray::sort
algorithm's default compare functionString
constructor and String methods when casting the this
object to a stringRegExp
constructorError
constructorsalert
, XMlHTTPRequest::open
, querySelector
, …The + operator on Date objects uses toString not valueOf. Also if valueOf returns a non-primitive value then the toString method is called next. (JavaScript - The definitive guide, section 3.14) Using your example:
var result = "4" + {
toString: function () {
return "4";
},
valueOf: function () {
return this; // returning an object, not a primitive
}
};
Result is now 44.